From e7ad0143a5c608c3b9ca7725fefc571a7db6fff0 Mon Sep 17 00:00:00 2001 From: Rafostar <40623528+Rafostar@users.noreply.github.com> Date: Mon, 30 Nov 2020 09:26:27 +0100 Subject: [PATCH] Use cubic scale for volume. Fixes #21 Volume sliders should usually adjust volume using cubic scale. This also changes max volume to 150% which should be louder than previous value anyway. --- clapper_src/controls.js | 57 ++++++++++++++++++++++------------------- clapper_src/misc.js | 22 +++++++++++++++- clapper_src/player.js | 7 +++-- clapper_src/widget.js | 15 +++++++---- 4 files changed, 67 insertions(+), 34 deletions(-) diff --git a/clapper_src/controls.js b/clapper_src/controls.js index 85c1f4a8..dec39228 100644 --- a/clapper_src/controls.js +++ b/clapper_src/controls.js @@ -315,7 +315,6 @@ class ClapperControls extends Gtk.Box inverted: true, value_pos: Gtk.PositionType.TOP, draw_value: false, - round_digits: 2, vexpand: true, }); this.volumeScale.connect( @@ -324,18 +323,38 @@ class ClapperControls extends Gtk.Box this.volumeScale.add_css_class('volumescale'); this.volumeAdjustment = this.volumeScale.get_adjustment(); - this.volumeAdjustment.set_upper(2); + this.volumeAdjustment.set_upper(Misc.maxVolume); this.volumeAdjustment.set_step_increment(0.05); this.volumeAdjustment.set_page_increment(0.05); - for(let i = 0; i <= 2; i++) { - let text = (i) ? `${i}00%` : '0%'; + for(let i of [0, 1, Misc.maxVolume]) { + let text = (!i) ? '0%' : (i % 1 === 0) ? `${i}00%` : `${i * 10}0%`; this.volumeScale.add_mark(i, Gtk.PositionType.LEFT, text); } this.volumeButton.popoverBox.append(this.volumeScale); } + _updateVolumeButtonIcon(volume) + { + let icon = (volume <= 0) + ? 'muted' + : (volume <= 0.3) + ? 'low' + : (volume <= 0.7) + ? 'medium' + : (volume <= 1) + ? 'high' + : 'overamplified'; + + let iconName = `audio-volume-${icon}-symbolic`; + if(this.volumeButton.icon_name === iconName) + return; + + this.volumeButton.set_icon_name(iconName); + debug(`set volume icon: ${icon}`); + } + _onRealize() { this.disconnect(this.realizeSignal); @@ -405,29 +424,15 @@ class ClapperControls extends Gtk.Box _onVolumeScaleValueChanged(scale) { - let volume = Number(scale.get_value().toFixed(2)); - let icon = (volume <= 0) - ? 'muted' - : (volume <= 0.33) - ? 'low' - : (volume <= 0.66) - ? 'medium' - : (volume <= 1) - ? 'high' - : 'overamplified'; - - let iconName = `audio-volume-${icon}-symbolic`; - if(this.volumeButton.icon_name !== iconName) - { - debug(`set volume icon: ${icon}`); - this.volumeButton.set_icon_name(iconName); - } - - if(this.currentVolume === volume) - return; - + let volume = scale.get_value(); + let linearVolume = Misc.getLinearValue(volume); let { player } = this.get_ancestor(Gtk.Grid); - player.set_volume(volume); + + player.set_volume(linearVolume); + + /* FIXME: Should be placed in 'volume-changed' + * event once we move to message bus API */ + this._updateVolumeButtonIcon(volume); } _onPositionScaleDragging(scale) diff --git a/clapper_src/misc.js b/clapper_src/misc.js index 0d6605da..b1ef3e2f 100644 --- a/clapper_src/misc.js +++ b/clapper_src/misc.js @@ -1,4 +1,4 @@ -const { Gio, GstPlayer, Gtk } = imports.gi; +const { Gio, GstAudio, GstPlayer, Gtk } = imports.gi; const Debug = imports.clapper_src.debug; var appName = 'Clapper'; @@ -11,6 +11,8 @@ var settings = new Gio.Settings({ schema_id: appId, }); +var maxVolume = 1.5; + let { debug } = Debug; let inhibitCookie; @@ -83,3 +85,21 @@ function getFormattedTime(time, showHours) let parsed = (hours) ? `${hours}:` : ''; return parsed + `${minutes}:${seconds}`; } + +function getCubicValue(linearVal) +{ + return GstAudio.StreamVolume.convert_volume( + GstAudio.StreamVolumeFormat.LINEAR, + GstAudio.StreamVolumeFormat.CUBIC, + linearVal + ); +} + +function getLinearValue(cubicVal) +{ + return GstAudio.StreamVolume.convert_volume( + GstAudio.StreamVolumeFormat.CUBIC, + GstAudio.StreamVolumeFormat.LINEAR, + cubicVal + ); +} diff --git a/clapper_src/player.js b/clapper_src/player.js index 4821c71d..a58ffcc6 100644 --- a/clapper_src/player.js +++ b/clapper_src/player.js @@ -28,6 +28,8 @@ class ClapperPlayer extends PlayerBase this.posY = 0; this.keyPressCount = 0; + this._maxVolume = Misc.getLinearValue(Misc.maxVolume); + this._playlist = []; this._trackId = 0; @@ -193,10 +195,11 @@ class ClapperPlayer extends PlayerBase { if(volume < 0) volume = 0; - else if(volume > 2) - volume = 2; + else if(volume > this._maxVolume) + volume = this._maxVolume; super.set_volume(volume); + debug(`set player volume: ${volume}`); } adjust_position(isIncrease) diff --git a/clapper_src/widget.js b/clapper_src/widget.js index 41c29734..884795fa 100644 --- a/clapper_src/widget.js +++ b/clapper_src/widget.js @@ -66,7 +66,9 @@ var Widget = GObject.registerClass({ this.player = new Player(); this.player.connect('position-updated', this._onPlayerPositionUpdated.bind(this)); this.player.connect('duration-changed', this._onPlayerDurationChanged.bind(this)); - this.player.connect('volume-changed', this._onPlayerVolumeChanged.bind(this)); + + /* FIXME: re-enable once ported to new GstPlayer API with messages bus */ + //this.player.pipeline.connect('notify::volume', this._onPlayerVolumeChanged.bind(this)); this.overlay.set_child(this.player.widget); this.overlay.add_overlay(this.revealerTop); @@ -462,15 +464,18 @@ var Widget = GObject.registerClass({ _onPlayerVolumeChanged(player) { + let volume = player.get_volume(); + /* FIXME: This check should not be needed, GstPlayer should not - * emit 'volume-changed' with the same values. It needs to be - * fixed inside GStreamer GstPlayer API */ - let volume = Number(player.get_volume().toFixed(2)); + * emit 'volume-changed' with the same values, but it does. */ if(volume === this.controls.currentVolume) return; + /* Once above is fixed in GstPlayer, remove this var too */ this.controls.currentVolume = volume; - this.controls.volumeScale.set_value(volume); + + let cubicVolume = Misc.getCubicValue(volume); + this.controls._updateVolumeButtonIcon(cubicVolume); } _onStateNotify(toplevel)