Commit fdf76fb1 authored by Agate's avatar Agate 💬
Browse files

Merge branch 'logarithmic-volume-slider' into 'develop'

Use logarithmic scale for volume slider.

Closes #1222

See merge request funkwhale/funkwhale!1235
parents 853f2187 8d9e7ca5
Logarithmic scale for volume slider (#1222)
\ No newline at end of file
// 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
......@@ -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 () {
......
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)
})
})
})
\ No newline at end of file
Supports Markdown
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