Use logarithmic scale for volume slider.

Fixes #1222
environments/review-docs-devel-1399dq/deployments/6607
Philipp Wolfer 2020-11-19 17:06:10 +01:00
rodzic 800105e2e6
commit 8d9e7ca52d
4 zmienionych plików z 71 dodań i 3 usunięć

Wyświetl plik

@ -0,0 +1 @@
Logarithmic scale for volume slider (#1222)

Wyświetl plik

@ -0,0 +1,32 @@
// Provides functions to convert between linear and logarithmic volume scales.
// The logarithmic volume from the UI is converted to a linear volume with a
// logarithmic function like exp(b*x)/a.
// Compare https://www.dr-lex.be/info-stuff/volumecontrols.html for how the
// values for a and b got derived.
const PARAM_A = 1000
const PARAM_B = Math.log(1000) // ~ 6.908
function toLinearVolumeScale(v) {
// Or as approximation:
// return Math.pow(v, 4)
if (v == 0.0) {
return 0.0
}
return Math.min(Math.exp(PARAM_B * v) / PARAM_A, 1.0)
}
function toLogarithmicVolumeScale(v) {
// Or as approximation:
// return Math.exp(Math.log(v) / 4)
if (v == 0.0) {
return 0.0
}
return Math.log(v * PARAM_A) / PARAM_B
}
exports.toLinearVolumeScale = toLinearVolumeScale
exports.toLogarithmicVolumeScale = toLogarithmicVolumeScale

Wyświetl plik

@ -29,7 +29,7 @@
<input
id="volume-slider"
type="range"
step="0.05"
step="0.02"
min="0"
max="1"
v-model="sliderVolume" />
@ -38,6 +38,7 @@
</template>
<script>
import { mapState, mapGetters, mapActions } from "vuex"
import { toLinearVolumeScale, toLogarithmicVolumeScale } from '@/audio/volume'
export default {
data () {
@ -49,10 +50,10 @@ export default {
computed: {
sliderVolume: {
get () {
return this.$store.state.player.volume
return toLogarithmicVolumeScale(this.$store.state.player.volume)
},
set (v) {
this.$store.commit("player/volume", v)
this.$store.commit("player/volume", toLinearVolumeScale(v))
}
},
labels () {

Wyświetl plik

@ -0,0 +1,34 @@
import { expect } from 'chai'
import { toLinearVolumeScale, toLogarithmicVolumeScale } from '@/audio/volume'
describe('store/auth', () => {
describe('toLinearVolumeScale', () => {
describe('it should return real 0', () => {
expect(toLinearVolumeScale(0.0)).to.equal(0.0)
})
describe('it should have logarithmic scale', () => {
expect(2 * toLinearVolumeScale(0.5)).to.be.closeTo(toLinearVolumeScale(0.6), 0.001)
})
describe('it should return full volume', () => {
expect(toLogarithmicVolumeScale(1.0)).to.be.closeTo(1.0, 0.001)
})
})
describe('toLogarithmicVolumeScale', () => {
describe('it should return real 0', () => {
expect(toLogarithmicVolumeScale(0.0)).to.equal(0.0)
})
describe('it should have logarithmic scale', () => {
expect(toLogarithmicVolumeScale(0.6)).to.be.closeTo(0.9261, 0.001)
expect(toLogarithmicVolumeScale(0.7)).to.be.closeTo(0.9483, 0.001)
})
describe('it should return full volume', () => {
expect(toLogarithmicVolumeScale(1.0)).to.be.closeTo(1.0, 0.001)
})
})
})