11/**
2- * Base class for volume transfer functions
2+ * Base class for volume transfer functions.
3+ *
4+ * Volume transfer functions convert between slider position (UI space) and
5+ * player volume (audio space). This allows different scaling behaviors like
6+ * linear or logarithmic (decibel-based) volume control.
37 */
48class VolumeTransfer {
59 /**
6- * Convert logarithmic ( slider) to linear (tech)
10+ * Convert slider position to player volume.
711 *
8- * @param {number } logarithmic - Volume from 0-1
9- * @return {number } Linear volume from 0-1
12+ * @param {number } sliderPosition - Slider position from 0-1
13+ * @return {number } Player volume from 0-1
1014 */
11- toLinear ( logarithmic ) {
15+ sliderToVolume ( sliderPosition ) {
1216 throw new Error ( 'Must be implemented by subclass' ) ;
1317 }
1418
1519 /**
16- * Convert linear (tech) to logarithmic ( slider)
20+ * Convert player volume to slider position.
1721 *
18- * @param {number } linear - Volume from 0-1
19- * @return {number } Logarithmic volume from 0-1
22+ * @param {number } volume - Player volume from 0-1
23+ * @return {number } Slider position from 0-1
2024 */
21- toLogarithmic ( linear ) {
25+ volumeToSlider ( volume ) {
2226 throw new Error ( 'Must be implemented by subclass' ) ;
2327 }
24-
25- getName ( ) {
26- return 'base' ;
27- }
2828}
2929
3030/**
31- * Linear transfer - no conversion (current default behavior)
31+ * Linear volume transfer - direct 1:1 mapping between slider and volume.
32+ *
33+ * This is the default behavior where moving the slider linearly adjusts
34+ * the volume linearly. Simple but may not match human perception of loudness.
3235 */
3336class LinearVolumeTransfer extends VolumeTransfer {
34- toLinear ( value ) {
35- return value ;
36- }
37-
38- toLogarithmic ( value ) {
39- return value ;
37+ /**
38+ * Convert slider position to player volume (1:1 mapping).
39+ *
40+ * @param {number } sliderPosition - Slider position from 0-1
41+ * @return {number } Player volume from 0-1
42+ */
43+ sliderToVolume ( sliderPosition ) {
44+ return sliderPosition ;
4045 }
4146
42- getName ( ) {
43- return 'linear' ;
47+ /**
48+ * Convert player volume to slider position (1:1 mapping).
49+ *
50+ * @param {number } volume - Player volume from 0-1
51+ * @return {number } Slider position from 0-1
52+ */
53+ volumeToSlider ( volume ) {
54+ return volume ;
4455 }
4556}
4657
4758/**
48- * Logarithmic transfer using decibel scaling
59+ * Logarithmic volume transfer using decibel scaling.
60+ *
61+ * Provides exponential volume changes as the slider moves linearly, which
62+ * better matches human perception of loudness. Uses decibel (dB) scaling
63+ * where volume = 10^(dB/20).
4964 */
5065class LogarithmicVolumeTransfer extends VolumeTransfer {
66+ /**
67+ * Creates a logarithmic volume transfer function.
68+ *
69+ * @param {number } [dbRange=50] - The decibel range for the transfer function.
70+ * Larger values create a more dramatic curve. Typical range: 40-60 dB.
71+ */
5172 constructor ( dbRange = 50 ) {
5273 super ( ) ;
5374 this . dbRange = dbRange ;
5475 this . offset = Math . pow ( 10 , - dbRange / 20 ) ;
5576 }
5677
5778 /**
58- * Convert logarithmic slider position to linear volume for tech
79+ * Convert slider position to player volume using logarithmic scaling.
5980 *
60- * @param {number } sliderPosition - Slider position (0-1)
61- * @return {number } Linear volume (0-1)
81+ * Applies exponential scaling so that linear slider movement produces
82+ * logarithmic volume changes, matching human loudness perception.
83+ *
84+ * @param {number } sliderPosition - Slider position from 0-1
85+ * @return {number } Player volume from 0-1
6286 */
63- toLinear ( sliderPosition ) {
87+ sliderToVolume ( sliderPosition ) {
6488 if ( sliderPosition <= 0 ) {
6589 return 0 ;
6690 }
@@ -70,35 +94,33 @@ class LogarithmicVolumeTransfer extends VolumeTransfer {
7094 }
7195
7296 const dB = sliderPosition * this . dbRange - this . dbRange ;
73- const linear = Math . pow ( 10 , dB / 20 ) ;
7497
75- return linear ;
98+ return Math . pow ( 10 , dB / 20 ) * ( 1 + this . offset ) ;
7699 }
77100
78101 /**
79- * Convert linear volume from tech to logarithmic slider position
102+ * Convert player volume to slider position using logarithmic scaling.
103+ *
104+ * Inverse of sliderToVolume - converts linear volume back to the
105+ * corresponding logarithmic slider position.
80106 *
81- * @param {number } linear - Linear volume ( 0-1)
82- * @return {number } Slider position ( 0-1)
107+ * @param {number } volume - Player volume from 0-1
108+ * @return {number } Slider position from 0-1
83109 */
84- toLogarithmic ( linear ) {
85- if ( linear <= 0 ) {
110+ volumeToSlider ( volume ) {
111+ if ( volume <= 0 ) {
86112 return 0 ;
87113 }
88114
89- if ( linear >= 1 ) {
115+ if ( volume >= 1 ) {
90116 return 1 ;
91117 }
92118
93- const dB = 20 * Math . log10 ( linear ) ;
119+ const dB = 20 * Math . log10 ( volume ) ;
94120 const position = ( dB + this . dbRange ) / this . dbRange ;
95121
96122 return position ;
97123 }
98-
99- getName ( ) {
100- return 'logarithmic' ;
101- }
102124}
103125
104126export default VolumeTransfer ;
0 commit comments