1+ import { MS_IN_SEC } from "@code-chronicles/util/timeConstants" ;
2+
13let audioContext : AudioContext | null = null ;
24
5+ const FADE_DURATION = 0.01 ;
6+
37/**
48 * Plays a sound using the Web Audio API.
59 *
@@ -8,21 +12,21 @@ let audioContext: AudioContext | null = null;
812 * @param durationMs - The duration of the sound in milliseconds.
913 * @param volumePct - The volume of the sound, typically between 0 and 1.
1014 */
11- export const playSound = (
15+ export function playSound (
1216 frequency : number ,
1317 durationMs : number ,
1418 volumePct : number ,
15- ) => {
19+ ) : void {
1620 if ( frequency <= 0 ) {
17- throw new Error ( "Frequency must be a positive number." ) ;
21+ throw new RangeError ( "Frequency must be a positive number." ) ;
1822 }
1923
2024 if ( durationMs <= 0 ) {
21- throw new Error ( "Duration must be a positive number." ) ;
25+ throw new RangeError ( "Duration must be a positive number." ) ;
2226 }
2327
2428 if ( volumePct < 0 || volumePct > 1 ) {
25- throw new Error ( "Volume must be between 0 and 1." ) ;
29+ throw new RangeError ( "Volume must be between 0 and 1." ) ;
2630 }
2731
2832 audioContext ??= new AudioContext ( ) ;
@@ -36,16 +40,16 @@ export const playSound = (
3640 // Creates the smooth fades-in / fade-out sound effect (Avoids the popping sounds)
3741 gainNode . gain . linearRampToValueAtTime (
3842 volumePct ,
39- audioContext . currentTime + 0.01 ,
43+ audioContext . currentTime + FADE_DURATION ,
4044 ) ;
4145 gainNode . gain . linearRampToValueAtTime (
4246 0 ,
43- audioContext . currentTime + durationMs / 1000 - 0.01 ,
47+ audioContext . currentTime + durationMs / MS_IN_SEC - FADE_DURATION ,
4448 ) ;
4549
4650 oscillatorNode . connect ( gainNode ) ;
4751 gainNode . connect ( audioContext . destination ) ;
4852
4953 oscillatorNode . start ( ) ;
50- oscillatorNode . stop ( audioContext . currentTime + durationMs / 1000 ) ;
51- } ;
54+ oscillatorNode . stop ( audioContext . currentTime + durationMs / MS_IN_SEC ) ;
55+ }
0 commit comments