Commit ce0b659a authored by Bilal Elmoussaoui's avatar Bilal Elmoussaoui

generate waveform for old recordings

parent 09a74f9f
Pipeline #202974 passed with stages
in 1 minute and 44 seconds
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<!-- Generated with glade 3.36.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="libhandy" version="0.0"/>
......@@ -132,6 +132,28 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkStack" id="waveformStack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="transition_type">crossfade</property>
<child>
<object class="GtkSpinner">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="active">True</property>
</object>
<packing>
<property name="name">loading</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
......@@ -296,6 +318,11 @@
<class name="pill-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
......@@ -464,21 +491,20 @@
</template>
<menu id="optionMenu">
<section>
<item>
<item>
<attribute name="action">recording.rename</attribute>
<attribute name="label" translatable="yes">Rename</attribute>
</item>
<item>
</item>
<item>
<attribute name="action">recording.export</attribute>
<attribute name="label" translatable="yes">Export</attribute>
</item>
</item>
</section>
</menu>
<object class="GtkSizeGroup">
<property name="mode">GTK_SIZE_GROUP_HORIZONTAL</property>
<widgets>
<widget name="rightStack"/>
<widget name="deleteBtnBox"/>
</widgets>
</object>
<widgets>
<widget name="rightStack"/>
<widget name="deleteBtnBox"/>
</widgets>
</object>
</interface>
......@@ -20,7 +20,6 @@
const { Gdk, Gio, GLib, GObject, Gst, Gtk, Handy } = imports.gi;
/* Translators: "Recordings" here refers to the name of the directory where the application places files */
var RecordingsDir = Gio.file_new_for_path(GLib.build_filenamev([GLib.get_user_data_dir(), pkg.name]));
var CacheDir = Gio.file_new_for_path(GLib.build_filenamev([GLib.get_user_cache_dir(), pkg.name]));
var Settings = new Gio.Settings({ schema: pkg.name });
......
/* exported Recording */
const { Gio, GLib, GObject, GstPbutils } = imports.gi;
const { Gio, GLib, GObject, Gst, GstPbutils } = imports.gi;
const { CacheDir } = imports.application;
const ByteArray = imports.byteArray;
var Recording = new GObject.registerClass({
Signals: {
'peaks-updated': {},
'peaks-loading': {},
},
Properties: {
'duration': GObject.ParamSpec.int(
......@@ -23,6 +24,7 @@ var Recording = new GObject.registerClass({
_init(file) {
this._file = file;
this._peaks = [];
this._loadedPeaks = [];
super._init({});
let info = file.query_info('time::created,time::modified', 0, null);
......@@ -123,7 +125,46 @@ var Recording = new GObject.registerClass({
log(`Error reading waveform data file: ${this.name}_data`);
}
});
} else {
this.emit('peaks-loading');
this.generatePeaks();
}
}
generatePeaks() {
const pipeline = Gst.parse_launch('uridecodebin name=uridecodebin ! audioconvert ! audio/x-raw,channels=1 ! level name=level ! fakesink name=faked');
let uridecodebin = pipeline.get_by_name('uridecodebin');
uridecodebin.set_property('uri', this.uri);
let fakesink = pipeline.get_by_name('faked');
fakesink.set_property('qos', false);
fakesink.set_property('sync', true);
const bus = pipeline.get_bus();
pipeline.set_state(Gst.State.PLAYING);
bus.add_signal_watch();
bus.connect('message', (_bus, message) => {
let s;
switch (message.type) {
case Gst.MessageType.ELEMENT:
s = message.get_structure();
if (s && s.has_name('level')) {
const peakVal = s.get_value('peak');
if (peakVal) {
const peak = peakVal.get_nth(0);
this._loadedPeaks.push(Math.pow(10, peak / 20));
}
}
break;
case Gst.MessageType.EOS:
this.peaks = this._loadedPeaks;
pipeline.set_state(Gst.State.NULL);
break;
}
});
}
});
......@@ -10,7 +10,7 @@ var RowState = {
var Row = GObject.registerClass({
Template: 'resource:///org/gnome/SoundRecorder/ui/row.ui',
InternalChildren: ['playbackStack', 'mainStack', 'playButton', 'pauseButton', 'name', 'entry', 'date', 'duration', 'revealer', 'playbackControls', 'rightStack', 'squeezer', 'saveBtn', 'renameBtn', 'exportBtn', 'saveBtn', 'rightStack', 'optionBox', 'seekBackward', 'seekForward', 'optionBtn', 'deleteBtn'],
InternalChildren: ['playbackStack', 'mainStack', 'playButton', 'waveformStack', 'pauseButton', 'name', 'entry', 'date', 'duration', 'revealer', 'playbackControls', 'rightStack', 'squeezer', 'saveBtn', 'renameBtn', 'exportBtn', 'saveBtn', 'rightStack', 'seekBackward', 'seekForward', 'optionBtn', 'deleteBtn'],
Signals: {
'play': { param_types: [GObject.TYPE_STRING] },
'pause': {},
......@@ -39,9 +39,7 @@ var Row = GObject.registerClass({
margin_left: 12,
margin_right: 12,
}, WaveType.PLAYER);
this._optionBox.add(this.waveform);
this._optionBox.reorder_child(this.waveform, 0);
this._waveformStack.add_named(this.waveform, 'wave');
recording.bind_property('name', this._name, 'label', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.DEFAULT);
recording.bind_property('name', this._entry, 'text', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.DEFAULT);
......@@ -92,9 +90,14 @@ var Row = GObject.registerClass({
this.waveform.peaks = this._recording.peaks;
this._recording.connect('peaks-updated', _ => {
this._waveformStack.visible_child_name = 'wave';
this.waveform.peaks = this._recording.peaks;
});
this._recording.connect('peaks-loading', _ => {
this._waveformStack.visible_child_name = 'loading';
});
recording.connect('notify::duration', () => {
this._duration.label = formatTime(recording.duration / Gst.SECOND);
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment