I am working on a program to convert text into morse code audio.
Say I type in sos
. My program will turn this into the array [1, 1, 1, 0, 2, 2, 2, 0, 1, 1, 1]
. Where s = dot dot dot
(or 1,1,1
), and o = dash dash dash
(or 2,2,2
). This part is quite easy.
Next, I have two sound files:
var dot = new Audio('dot.mp3');
var dash = new Audio('dash.mp3');
My goal is to have a function that will play dot.mp3
when it sees a 1
, and dash.mp3
when it sees a 2
, and pauses when it sees a 0
.
The following sort of/ kind of/ sometimes works, but I think it's fundamentally flawed and I don't know how to fix it.
function playMorseArr(morseArr) {
for (let i = 0; i < morseArr.length; i++) {
setTimeout(function() {
if (morseArr[i] === 1) {
dot.play();
}
if (morseArr[i] === 2) {
dash.play();
}
}, 250*i);
}
}
The problem:
I can loop over the array, and play the sound files, but timing is a challenge. If I don't set the setTimeout()
interval just right, if the last audio file is not done playing and the 250ms
has elapsed, the next element in the array will be skipped. So dash.mp3
is longer than dot.mp3
. If my timing is too short, I might hear [dot dot dot pause dash dash pause dot dot dot]
, or something to that effect.
The effect I want
I want the program to go like this (in pseudocode):
- look at the
ith
array element - if
1
or2
, start playing sound file or else create a pause - wait for the sound file or pause to finish
- increment
i
and go back to step 1
What I have thought of, but don't know how to implement
So the pickle is that I want the loop to proceed synchronously. I've used promises in situations where I had several functions that I wanted executed in a specific order, but how would I chain an unknown number of functions?
I also considered using custom events, but I have the same problem.