【发布时间】:2019-06-27 19:53:19
【问题描述】:
我正在开发一个将文本转换为摩尔斯电码音频的程序。
假设我输入sos。我的程序会将其转换为数组[1, 1, 1, 0, 2, 2, 2, 0, 1, 1, 1]。其中s = dot dot dot(或1,1,1)和o = dash dash dash(或2,2,2)。这部分很简单。
接下来,我有两个声音文件:
var dot = new Audio('dot.mp3');
var dash = new Audio('dash.mp3');
我的目标是有一个函数,当它看到1时播放dot.mp3,当它看到2时播放dash.mp3,当它看到0时暂停。
以下类型/类型/有时有效,但我认为它存在根本缺陷,我不知道如何解决。
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);
}
}
问题:
我可以遍历数组并播放声音文件,但时间是一个挑战。如果我没有将setTimeout() 间隔设置得恰到好处,如果最后一个音频文件没有播放完毕并且250ms 已经过去,则将跳过数组中的下一个元素。所以dash.mp3 比dot.mp3 长。如果我的时间太短,我可能会听到[dot dot dot pause dash dash pause dot dot dot],或类似的东西。
我想要的效果
我希望程序像这样运行(在伪代码中):
- 查看
ith数组元素 - 如果是
1或2,则开始播放声音文件或创建暂停 - 等待声音文件或暂停完成
- 增加
i并返回步骤1
想到的,不知道如何实现
所以泡菜是我希望循环同步进行。我曾在我想要以特定顺序执行的多个函数的情况下使用 Promise,但我将如何链接未知数量的函数?
我也考虑过使用自定义事件,但我遇到了同样的问题。
【问题讨论】:
-
请注意,在正确的摩尔斯电码中,“一个单词的字母由一个持续时间等于三个点的空格分隔,并且单词由一个等于七个点的空格分隔。” (来自维基百科)破折号是点长度的三倍。您可能需要一个空格字符。
-
超时并不是解决此类问题的最佳方法。但如果您必须使用它们,不要依赖精确的延迟。通过运行更小的间隔并测量/累积每次迭代的实际经过时间,然后根据实际经过的时间量在正确的时刻触发事件,您将获得更一致的结果。
标签: javascript html5-audio synchronous playback