diff --git a/src/bundles/sound/functions.ts b/src/bundles/sound/functions.ts
index d8b1d20cb..f1d296e73 100644
--- a/src/bundles/sound/functions.ts
+++ b/src/bundles/sound/functions.ts
@@ -1,19 +1,19 @@
/**
- * The sounds library provides functions for constructing and playing sounds.
+ * The `sound` module provides functions for constructing and playing sounds.
*
* A wave is a function that takes in a number `t` and returns
* a number representing the amplitude at time `t`.
* The amplitude should fall within the range of [-1, 1].
*
- * A Sound is a pair(wave, duration) where duration is the length of the sound in seconds.
+ * A Sound is a pair(wave, duration) where duration is the length of the Sound in seconds.
* The constructor make_sound and accessors get_wave and get_duration are provided.
*
* Sound Discipline:
- * For all sounds, the wave function applied to and time `t` beyond its duration returns 0, that is:
+ * For all Sounds, the wave function applied to and time `t` beyond its duration returns 0, that is:
* `(get_wave(sound))(get_duration(sound) + x) === 0` for any x >= 0.
*
* Two functions which combine Sounds, `consecutively` and `simultaneously` are given.
- * Additionally, we provide sound transformation functions `adsr` and `phase_mod`
+ * Additionally, we provide Sound transformation functions `adsr` and `phase_mod`
* which take in a Sound and return a Sound.
*
* Finally, the provided `play` function takes in a Sound and plays it using your
@@ -127,7 +127,7 @@ const recording_signal_ms = 100;
const pre_recording_signal_pause_ms = 200;
function play_recording_signal() {
- play_concurrently(sine_sound(1200, recording_signal_ms / 1000));
+ play(sine_sound(1200, recording_signal_ms / 1000));
}
// eslint-disable-next-line @typescript-eslint/no-shadow
@@ -175,10 +175,11 @@ export function init_record(): string {
}
/**
- * takes a buffer
duration (in seconds) as argument, and
+ * Records a sound until the returned stop function is called.
+ * Takes a buffer
duration (in seconds) as argument, and
* returns a nullary stop function stop
. A call
- * stop()
returns a sound promise: a nullary function
- * that returns a sound. Example:
init_record();
+ * stop()
returns a Sound promise: a nullary function
+ * that returns a Sound. Example: init_record();
* const stop = record(0.5);
* // record after 0.5 seconds. Then in next query:
* const promise = stop();
@@ -188,7 +189,7 @@ export function init_record(): string {
* @param buffer - pause before recording, in seconds
* @returns nullary stop
function;
* stop()
stops the recording and
- * returns a sound promise: a nullary function that returns the recorded sound
+ * returns a Sound promise: a nullary function that returns the recorded Sound
*/
export function record(buffer: number): () => () => Sound {
check_permission();
@@ -213,15 +214,15 @@ export function record(buffer: number): () => () => Sound {
/**
* Records a sound of given duration
in seconds, after
* a buffer
also in seconds, and
- * returns a sound promise: a nullary function
- * that returns a sound. Example: init_record();
+ * returns a Sound promise: a nullary function
+ * that returns a Sound. Example: init_record();
* const promise = record_for(2, 0.5);
- * // In next query, you can play the promised sound, by
+ * // In next query, you can play the promised Sound, by
* // applying the promise:
* play(promise());
* @param duration duration in seconds
* @param buffer pause before recording, in seconds
- * @return promise
: nullary function which returns recorded sound
+ * @return promise
: nullary function which returns recorded Sound
*/
export function record_for(duration: number, buffer: number): () => Sound {
recorded_sound = undefined;
@@ -270,8 +271,8 @@ export function record_for(duration: number, buffer: number): () => Sound {
* that takes in a non-negative input time and returns an amplitude
* between -1 and 1.
*
- * @param wave wave function of the sound
- * @param duration duration of the sound
+ * @param wave wave function of the Sound
+ * @param duration duration of the Sound
* @return with wave as wave function and duration as duration
* @example const s = make_sound(t => Math_sin(2 * Math_PI * 440 * t), 5);
*/
@@ -319,33 +320,33 @@ export function is_sound(x: any): x is Sound {
/**
* Plays the given Wave using the computer’s sound device, for the duration
* given in seconds.
- * The sound is only played if no other sounds are currently being played.
*
* @param wave the wave function to play, starting at 0
- * @return the given sound
+ * @return the resulting Sound
* @example play_wave(t => math_sin(t * 3000), 5);
*/
-export function play_wave(wave: Wave, duration: number): AudioPlayed {
+export function play_wave(wave: Wave, duration: number): Sound {
return play(make_sound(wave, duration));
}
/**
* Plays the given Sound using the computer’s sound device.
- * The sound is only played if no other sounds are currently being played.
+ * The sound is added to a list of sounds to be played one-at-a-time
+ * in a Source Academy tab.
*
- * @param sound the sound to play
- * @return the given sound
- * @example play(sine_sound(440, 5));
+ * @param sound the Sound to play
+ * @return the given Sound
+ * @example play_in_tab(sine_sound(440, 5));
*/
-export function play(sound: Sound): AudioPlayed {
+export function play_in_tab(sound: Sound): Sound {
// Type-check sound
if (!is_sound(sound)) {
- throw new Error(`${play.name} is expecting sound, but encountered ${sound}`);
+ throw new Error(`${play_in_tab.name} is expecting sound, but encountered ${sound}`);
// If a sound is already playing, terminate execution.
} else if (isPlaying) {
- throw new Error(`${play.name}: audio system still playing previous sound`);
+ throw new Error(`${play_in_tab.name}: audio system still playing previous sound`);
} else if (get_duration(sound) < 0) {
- throw new Error(`${play.name}: duration of sound is negative`);
+ throw new Error(`${play_in_tab.name}: duration of sound is negative`);
} else {
// Instantiate audio context if it has not been instantiated.
if (!audioplayer) {
@@ -391,43 +392,31 @@ export function play(sound: Sound): AudioPlayed {
riffwave.header.bitsPerSample = 16;
riffwave.Make(channel);
- /*
- const audio = new Audio(riffwave.dataURI);
- const source2 = audioplayer.createMediaElementSource(audio);
- source2.connect(audioplayer.destination);
-
- // Connect data to output destination
- isPlaying = true;
- audio.play();
- audio.onended = () => {
- source2.disconnect(audioplayer.destination);
- isPlaying = false;
- }; */
-
const soundToPlay = {
toReplString: () => '',
dataUri: riffwave.dataURI,
};
audioPlayed.push(soundToPlay);
- return soundToPlay;
+ return sound;
}
}
/**
* Plays the given Sound using the computer’s sound device
- * on top of any sounds that are currently playing.
+ * on top of any Sounds that are currently playing.
*
- * @param sound the sound to play
- * @example play_concurrently(sine_sound(440, 5));
+ * @param sound the Sound to play
+ * @return the given Sound
+ * @example play(sine_sound(440, 5));
*/
-export function play_concurrently(sound: Sound): void {
+export function play(sound: Sound): Sound {
// Type-check sound
if (!is_sound(sound)) {
throw new Error(
- `${play_concurrently.name} is expecting sound, but encountered ${sound}`,
+ `${play.name} is expecting sound, but encountered ${sound}`,
);
- } else if (get_duration(sound) <= 0) {
- // Do nothing
+ } else if (get_duration(sound) < 0) {
+ throw new Error(`${play.name}: duration of sound is negative`);
} else {
// Instantiate audio context if it has not been instantiated.
if (!audioplayer) {
@@ -475,6 +464,7 @@ export function play_concurrently(sound: Sound): void {
source.disconnect(audioplayer.destination);
isPlaying = false;
};
+ return sound;
}
}
@@ -489,10 +479,10 @@ export function stop(): void {
// Primitive sounds
/**
- * Makes a noise sound with given duration
+ * Makes a noise Sound with given duration
*
* @param duration the duration of the noise sound
- * @return resulting noise sound
+ * @return resulting noise Sound
* @example noise_sound(5);
*/
export function noise_sound(duration: number): Sound {
@@ -500,10 +490,10 @@ export function noise_sound(duration: number): Sound {
}
/**
- * Makes a silence sound with given duration
+ * Makes a silence Sound with given duration
*
- * @param duration the duration of the silence sound
- * @return resulting silence sound
+ * @param duration the duration of the silence Sound
+ * @return resulting silence Sound
* @example silence_sound(5);
*/
export function silence_sound(duration: number): Sound {
@@ -511,11 +501,11 @@ export function silence_sound(duration: number): Sound {
}
/**
- * Makes a sine wave sound with given frequency and duration
+ * Makes a sine wave Sound with given frequency and duration
*
- * @param freq the frequency of the sine wave sound
- * @param duration the duration of the sine wave sound
- * @return resulting sine wave sound
+ * @param freq the frequency of the sine wave Sound
+ * @param duration the duration of the sine wave Sound
+ * @return resulting sine wave Sound
* @example sine_sound(440, 5);
*/
export function sine_sound(freq: number, duration: number): Sound {
@@ -523,11 +513,11 @@ export function sine_sound(freq: number, duration: number): Sound {
}
/**
- * Makes a square wave sound with given frequency and duration
+ * Makes a square wave Sound with given frequency and duration
*
- * @param freq the frequency of the square wave sound
- * @param duration the duration of the square wave sound
- * @return resulting square wave sound
+ * @param freq the frequency of the square wave Sound
+ * @param duration the duration of the square wave Sound
+ * @return resulting square wave Sound
* @example square_sound(440, 5);
*/
export function square_sound(f: number, duration: number): Sound {
@@ -545,11 +535,11 @@ export function square_sound(f: number, duration: number): Sound {
}
/**
- * Makes a triangle wave sound with given frequency and duration
+ * Makes a triangle wave Sound with given frequency and duration
*
- * @param freq the frequency of the triangle wave sound
- * @param duration the duration of the triangle wave sound
- * @return resulting triangle wave sound
+ * @param freq the frequency of the triangle wave Sound
+ * @param duration the duration of the triangle wave Sound
+ * @return resulting triangle wave Sound
* @example triangle_sound(440, 5);
*/
export function triangle_sound(freq: number, duration: number): Sound {
@@ -569,11 +559,11 @@ export function triangle_sound(freq: number, duration: number): Sound {
}
/**
- * Makes a sawtooth wave sound with given frequency and duration
+ * Makes a sawtooth wave Sound with given frequency and duration
*
- * @param freq the frequency of the sawtooth wave sound
- * @param duration the duration of the sawtooth wave sound
- * @return resulting sawtooth wave sound
+ * @param freq the frequency of the sawtooth wave Sound
+ * @param duration the duration of the sawtooth wave Sound
+ * @return resulting sawtooth wave Sound
* @example sawtooth_sound(440, 5);
*/
export function sawtooth_sound(freq: number, duration: number): Sound {
@@ -594,11 +584,11 @@ export function sawtooth_sound(freq: number, duration: number): Sound {
/**
* Makes a new Sound by combining the sounds in a given list
- * where the second sound is appended to the end of the first sound,
- * the third sound is appended to the end of the second sound, and
- * so on. The effect is that the sounds in the list are joined end-to-end
+ * where the second Sound is appended to the end of the first Sound,
+ * the third Sound is appended to the end of the second Sound, and
+ * so on. The effect is that the Sounds in the list are joined end-to-end
*
- * @param list_of_sounds given list of sounds
+ * @param list_of_sounds given list of Sounds
* @return the combined Sound
* @example consecutively(list(sine_sound(200, 2), sine_sound(400, 3)));
*/
@@ -615,10 +605,10 @@ export function consecutively(list_of_sounds: List): Sound {
}
/**
- * Makes a new Sound by combining the sounds in a given list
- * where all the sounds are overlapped on top of each other.
+ * Makes a new Sound by combining the Sounds in a given list
+ * where all the Sounds are overlapped on top of each other.
*
- * @param list_of_sounds given list of sounds
+ * @param list_of_sounds given list of Sounds
* @return the combined Sound
* @example simultaneously(list(sine_sound(200, 2), sine_sound(400, 3)))
*/
@@ -730,7 +720,7 @@ export function stacking_adsr(
}
/**
- * Returns a SoundTransformer which uses its argument
+ * Returns a Sound transformer which uses its argument
* to modulate the phase of a (carrier) sine wave
* of given frequency and duration with a given Sound.
* Modulating with a low frequency Sound results in a vibrato effect.
@@ -738,7 +728,7 @@ export function stacking_adsr(
* the sine wave frequency results in more complex wave forms.
*
* @param freq the frequency of the sine wave to be modulated
- * @param duration the duration of the output soud
+ * @param duration the duration of the output Sound
* @param amount the amount of modulation to apply to the carrier sine wave
* @return function which takes in a Sound and returns a Sound
* @example phase_mod(440, 5, 1)(sine_sound(220, 5));
diff --git a/src/bundles/sound/index.ts b/src/bundles/sound/index.ts
index 7b128739f..9d0b2c7cb 100644
--- a/src/bundles/sound/index.ts
+++ b/src/bundles/sound/index.ts
@@ -21,8 +21,8 @@ export {
phase_mod,
piano,
// Play-related
+ play_in_tab,
play,
- play_concurrently,
play_wave,
record,
record_for,
diff --git a/src/bundles/stereo_sound/functions.ts b/src/bundles/stereo_sound/functions.ts
index 64ee4fa0d..84ddb23ca 100644
--- a/src/bundles/stereo_sound/functions.ts
+++ b/src/bundles/stereo_sound/functions.ts
@@ -1,9 +1,10 @@
/**
*
- * The stereo sounds library build on the sounds library by accommodating stereo sounds.
- * Within this library, all sounds are represented in stereo, with two waves, left and right.
+ * The `stereo_sound` module build on the `sound` module by accommodating stereo sounds.
+ * Within this module, all Sounds are represented in stereo, with two waves, left and right.
*
- * A Stereo Sound is a `pair(pair(left_wave, right_wave), duration)` where duration is the length of the sound in seconds.
+ * A Stereo Sound (just denoted as "Sound" in this document) is
+ a `pair(pair(left_wave, right_wave), duration)` where duration is the length of the Sound in seconds.
* The constructor `make_stereo_sound` and accessors `get_left_wave`, `get_right_wave`, and `get_duration` are provided.
* The `make_sound` constructor from sounds is syntatic sugar for `make_stereo_sounds` with equal waves.
*
@@ -114,7 +115,7 @@ function start_recording(mediaRecorder: MediaRecorder) {
const recording_signal_duration_ms = 100;
function play_recording_signal() {
- play_concurrently(sine_sound(1200, recording_signal_duration_ms / 1000));
+ play(sine_sound(1200, recording_signal_duration_ms / 1000));
}
// eslint-disable-next-line @typescript-eslint/no-shadow
@@ -162,20 +163,21 @@ export function init_record(): string {
}
/**
- * takes a buffer
duration (in seconds) as argument, and
+ * Records a sound until the returned stop function is called.
+ * Takes a buffer
duration (in seconds) as argument, and
* returns a nullary stop function stop
. A call
- * stop()
returns a sound promise: a nullary function
- * that returns a sound. Example: init_record();
+ * stop()
returns a Sound promise: a nullary function
+ * that returns a Sound. Example: init_record();
* const stop = record(0.5);
* // record after 0.5 seconds. Then in next query:
* const promise = stop();
- * // In next query, you can play the promised sound, by
+ * // In next query, you can play the promised Sound, by
* // applying the promise:
* play(promise());
* @param buffer - pause before recording, in seconds
* @returns nullary stop
function;
* stop()
stops the recording and
- * returns a sound promise: a nullary function that returns the recorded sound
+ * returns a sound promise: a nullary function that returns the recorded Sound
*/
export function record(buffer: number): () => () => Sound {
check_permission();
@@ -200,8 +202,8 @@ export function record(buffer: number): () => () => Sound {
/**
* Records a sound of given duration
in seconds, after
* a buffer
also in seconds, and
- * returns a sound promise: a nullary function
- * that returns a sound. Example: init_record();
+ * returns a Sound promise: a nullary function
+ * that returns a Sound. Example: init_record();
* const promise = record_for(2, 0.5);
* // In next query, you can play the promised sound, by
* // applying the promise:
@@ -248,11 +250,11 @@ export function record_for(duration: number, buffer: number): () => Sound {
* that takes in a non-negative input time and returns an amplitude
* between -1 and 1.
*
- * @param left_wave wave function of the left channel of the sound
- * @param right_wave wave function of the right channel of the sound
- * @param duration duration of the sound
- * @return resulting stereo sound
- * @example const s = make_stereo_sound(t => Math_sin(2 * Math_PI * 440 * t), t => Math_sin(2 * Math_PI * 300 * t), 5);
+ * @param left_wave wave function of the left channel of the Sound
+ * @param right_wave wave function of the right channel of the Sound
+ * @param duration duration of the Sound
+ * @return resulting stereo Sound
+ * @example const s = make_stereo_sound(t => math_sin(2 * math_PI * 440 * t), t => math_sin(2 * math_PI * 300 * t), 5);
*/
export function make_stereo_sound(
left_wave: Wave,
@@ -274,10 +276,10 @@ export function make_stereo_sound(
* that takes in a non-negative input time and returns an amplitude
* between -1 and 1.
*
- * @param wave wave function of the sound
- * @param duration duration of the sound
- * @return with wave as wave function and duration as duration
- * @example const s = make_sound(t => Math_sin(2 * Math_PI * 440 * t), 5);
+ * @param wave wave function of the Sound
+ * @param duration duration of the Sound
+ * @return Sound with the given `wave` function for both channels and `duration` as duration
+ * @example const s = make_sound(t => math_sin(2 * math_PI * 440 * t), 5);
*/
export function make_sound(wave: Wave, duration: number): Sound {
return make_stereo_sound(wave, wave, duration);
@@ -288,7 +290,7 @@ export function make_sound(wave: Wave, duration: number): Sound {
*
* @param sound given Sound
* @return the wave function of the Sound
- * @example get_wave(make_sound(t => Math_sin(2 * Math_PI * 440 * t), 5)); // Returns t => Math_sin(2 * Math_PI * 440 * t)
+ * @example get_wave(make_sound(t => math_sin(2 * math_PI * 440 * t), 5)); // Returns t => math_sin(2 * math_PI * 440 * t)
*/
export function get_left_wave(sound: Sound): Wave {
return head(head(sound));
@@ -299,7 +301,7 @@ export function get_left_wave(sound: Sound): Wave {
*
* @param sound given Sound
* @return the wave function of the Sound
- * @example get_wave(make_sound(t => Math_sin(2 * Math_PI * 440 * t), 5)); // Returns t => Math_sin(2 * Math_PI * 440 * t)
+ * @example get_wave(make_sound(t => math_sin(2 * math_PI * 440 * t), 5)); // Returns t => math_sin(2 * math_PI * 440 * t)
*/
export function get_right_wave(sound: Sound): Wave {
return tail(head(sound));
@@ -310,7 +312,7 @@ export function get_right_wave(sound: Sound): Wave {
*
* @param sound given Sound
* @return the duration of the Sound
- * @example get_duration(make_sound(t => Math_sin(2 * Math_PI * 440 * t), 5)); // Returns 5
+ * @example get_duration(make_sound(t => math_sin(2 * math_PI * 440 * t), 5)); // Returns 5
*/
export function get_duration(sound: Sound): number {
return tail(sound);
@@ -335,13 +337,12 @@ export function is_sound(x: any): boolean {
/**
* Plays the given Wave using the computer’s sound device, for the duration
* given in seconds.
- * The sound is only played if no other sounds are currently being played.
*
* @param wave the wave function to play, starting at 0
- * @return the given sound
+ * @return the given Sound
* @example play_wave(t => math_sin(t * 3000), 5);
*/
-export function play_wave(wave: Wave, duration: number): AudioPlayed {
+export function play_wave(wave: Wave, duration: number): Sound {
return play(make_sound(wave, duration));
}
@@ -349,38 +350,38 @@ export function play_wave(wave: Wave, duration: number): AudioPlayed {
* Plays the given two Waves using the computer’s sound device, for the duration
* given in seconds. The first Wave is for the left channel, the second for the
* right channel.
- * The sound is only played if no other sounds are currently being played.
*
* @param wave1 the wave function to play on the left channel, starting at 0
* @param wave2 the wave function to play on the right channel, starting at 0
- * @return the given sound
+ * @return the given Sound
* @example play_waves(t => math_sin(t * 3000), t => math_sin(t * 6000), 5);
*/
export function play_waves(
wave1: Wave,
wave2: Wave,
duration: number,
-): AudioPlayed {
+): Sound {
return play(make_stereo_sound(wave1, wave2, duration));
}
/**
* Plays the given Sound using the computer’s sound device.
- * The sound is only played if no other sounds are currently being played.
+ * The Sound is added to a list of Sounds to be played one-at-a-time
+ * in a Source Academy tab.
*
- * @param sound the sound to play
- * @return the given sound
- * @example play(sine_sound(440, 5));
+ * @param sound the Sound to play
+ * @return the given Sound
+ * @example play_in_tab(sine_sound(440, 5));
*/
-export function play(sound: Sound): AudioPlayed {
+export function play_in_tab(sound: Sound): Sound {
// Type-check sound
if (!is_sound(sound)) {
- throw new Error(`${play.name} is expecting sound, but encountered ${sound}`);
+ throw new Error(`${play_in_tab.name} is expecting sound, but encountered ${sound}`);
// If a sound is already playing, terminate execution.
} else if (isPlaying) {
- throw new Error(`${play.name}: audio system still playing previous sound`);
+ throw new Error(`${play_in_tab.name}: audio system still playing previous sound`);
} else if (get_duration(sound) < 0) {
- throw new Error(`${play.name}: duration of sound is negative`);
+ throw new Error(`${play_in_tab.name}: duration of sound is negative`);
} else {
// Instantiate audio context if it has not been instantiated.
if (!audioplayer) {
@@ -450,96 +451,89 @@ export function play(sound: Sound): AudioPlayed {
riffwave.header.bitsPerSample = 16;
riffwave.Make(channel);
- /*
- const audio = new Audio(riffwave.dataURI);
- const source2 = audioplayer.createMediaElementSource(audio);
- source2.connect(audioplayer.destination);
-
- // Connect data to output destination
- isPlaying = true;
- audio.play();
- audio.onended = () => {
- source2.disconnect(audioplayer.destination);
- isPlaying = false;
- }; */
-
const audio = {
toReplString: () => '',
dataUri: riffwave.dataURI,
};
audioPlayed.push(audio);
- return audio;
+ return sound;
}
}
/**
* Plays the given Sound using the computer’s sound device
- * on top of any sounds that are currently playing.
+ * on top of any Sounds that are currently playing.
*
- * @param sound the sound to play
- * @example play_concurrently(sine_sound(440, 5));
+ * @param sound the Sound to play
+ * @return the given Sound
+ * @example play(sine_sound(440, 5));
*/
-export function play_concurrently(sound: Sound): void {
+export function play(sound: Sound): Sound {
// Type-check sound
if (!is_sound(sound)) {
- throw new Error(
- `${play_concurrently.name} is expecting sound, but encountered ${sound}`,
- );
- } else if (get_duration(sound) <= 0) {
- // Do nothing
+ throw new Error(`${play.name} is expecting sound, but encountered ${sound}`);
+ // If a sound is already playing, terminate execution.
+ } else if (isPlaying) {
+ throw new Error(`${play.name}: audio system still playing previous sound`);
+ } else if (get_duration(sound) < 0) {
+ throw new Error(`${play.name}: duration of sound is negative`);
} else {
// Instantiate audio context if it has not been instantiated.
if (!audioplayer) {
init_audioCtx();
}
- const channel: number[] = Array[2 * Math.ceil(FS * get_duration(sound))];
+ const channel: number[] = [];
+ const len = Math.ceil(FS * get_duration(sound));
let Ltemp: number;
let Rtemp: number;
- let prev_value = 0;
+ let Lprev_value = 0;
+ let Rprev_value = 0;
const left_wave = get_left_wave(sound);
-
- for (let i = 0; i < channel.length; i += 2) {
+ const right_wave = get_right_wave(sound);
+ for (let i = 0; i < len; i += 1) {
Ltemp = left_wave(i / FS);
// clip amplitude
if (Ltemp > 1) {
- channel[i] = 1;
+ channel[2 * i] = 1;
} else if (Ltemp < -1) {
- channel[i] = -1;
+ channel[2 * i] = -1;
} else {
- channel[i] = Ltemp;
+ channel[2 * i] = Ltemp;
}
// smoothen out sudden cut-outs
- if (channel[i] === 0 && Math.abs(channel[i] - prev_value) > 0.01) {
- channel[i] = prev_value * 0.999;
+ if (
+ channel[2 * i] === 0
+ && Math.abs(channel[2 * i] - Lprev_value) > 0.01
+ ) {
+ channel[2 * i] = Lprev_value * 0.999;
}
- prev_value = channel[i];
- }
+ Lprev_value = channel[2 * i];
- prev_value = 0;
- const right_wave = get_right_wave(sound);
- for (let i = 1; i < channel.length; i += 2) {
Rtemp = right_wave(i / FS);
// clip amplitude
if (Rtemp > 1) {
- channel[i] = 1;
+ channel[2 * i + 1] = 1;
} else if (Rtemp < -1) {
- channel[i] = -1;
+ channel[2 * i + 1] = -1;
} else {
- channel[i] = Rtemp;
+ channel[2 * i + 1] = Rtemp;
}
// smoothen out sudden cut-outs
- if (channel[i] === 0 && Math.abs(channel[i] - prev_value) > 0.01) {
- channel[i] = prev_value * 0.999;
+ if (
+ channel[2 * i + 1] === 0
+ && Math.abs(channel[2 * i] - Rprev_value) > 0.01
+ ) {
+ channel[2 * i + 1] = Rprev_value * 0.999;
}
- prev_value = channel[i];
+ Rprev_value = channel[2 * i + 1];
}
// quantize
@@ -563,6 +557,7 @@ export function play_concurrently(sound: Sound): void {
source2.disconnect(audioplayer.destination);
isPlaying = false;
};
+ return sound;
}
}
diff --git a/src/bundles/stereo_sound/index.ts b/src/bundles/stereo_sound/index.ts
index abd2dd07b..40f02ec2a 100644
--- a/src/bundles/stereo_sound/index.ts
+++ b/src/bundles/stereo_sound/index.ts
@@ -10,10 +10,10 @@ export {
pan,
pan_mod,
// Play-related
- play,
+ play_in_tab,
play_wave,
play_waves,
- play_concurrently,
+ play,
stop,
// Recording
init_record,