我使用 SoX 来生成这个声音:
$ play -n synth 1 pluck E3 repeat 2
我设法在一个新的终端选项卡中同时播放另一个模式,比如说
$ play -n synth 1.5 pluck C3 repeat 2
。有没有办法在同一个 bash 脚本中同时播放这两种模式?
这将实现您所需要的,在左声道上播放 E3,在右声道上播放 C3:
$ play -n synth 1 pluck E3 pluck C3 repeat 2
如果您想在两个通道上播放两个音符,请添加通道效果:
$ play -n synth 1 pluck E3 pluck C3 repeat 2 channels 1
摘自SoX手册,synth效果 http://sox.sourceforge.net/sox.html
...多个合成器效果可以级联以产生更复杂的波形;...
为了解决在同一终端中同时运行两个
play
命令的具体问题,以下是当您使用 &
绑定两个命令时会发生什么情况的解释和解决方法:
$ play -n synth 1 pluck E3 & play -n synth 1 pluck E3
[1] 15682
(snipped information about audio file)
In:0.00% 00:00:01.02 [00:00:00.00] Out:48.0k [ | ] Hd:0.0 Clip:0
Done.
[1]+ Stopped play -n synth 1 pluck E3
$ fg
play -n synth 1 pluck E3
In:0.00% 00:00:01.02 [00:00:00.00] Out:48.0k [ | ] Hd:0.0 Clip:0
Done.
看到
[1]+ Stopped
线了吗?这意味着您的第一个 play
进程已进入睡眠状态。这就是为什么我必须运行 fg
来唤醒它并将其带到前台。
为何停止?因为第一个
play
命令尝试向终端读取或写入某些内容,而这只允许前台进程(第二个 play
命令)。作为后台进程,它收到 SIGTTIN 或 SIGTTOU 信号,迫使其停止。
如何解决这个问题?通过阻止后台
play
向终端读取和写入任何内容:
play -n synth 1 pluck E3 < /dev/null > /dev/null 2>&1 & { sleep 0.5; play -n synth 1 pluck E3; }
--no-show-progress
(-q
) 和 -V0
选项似乎足够了,尽管我不能向你保证这在所有情况下都有效,与上面的命令相反:
play -q -V0 -n synth 1 pluck E3 & { sleep 0.5; play -n synth 1 pluck E3; }
纠正您提出的几点:
play ..stuff.. </dev/null &
足以防止其停止。-q
播放,安静其输出,也会告诉它不要从标准输入读取,所以play -q ..stuff.. &
也可以工作。工作示例[后台但持续的播放命令]:
play -n synth 5 pluck E3 vol .5 </dev/null &
cat /dev/null | play -n synth 5 pluck E3 vol .5 &
play -q -n synth 5 pluck E3 vol .5 &
更好的例子(模拟其中一个仪式敲击碗的声音):
/usr/bin/play -q -n rate -m -v synth 4 0 25 sine F4 synth 4 0 25 sine fmod 1.8 gain -2 reverb 20 50 100 100 gain -1 fade l .01 4 4 vol 1.0 & echo "...Ahhah..!"
(注意 -q,没有
在不查看源代码的情况下,我推测 play 处理 ^C 的方式是从终端读取。我不知道它还会读什么?但手册页指出,如果播放多个文件,它将使用 ^C 跳过一个文件,而播放一个“东西”时 ^C 将中止它。
为了测试这一点,我做了:
play a.wav b.wav
# ^C 将跳至 b.wav
play -q a.wav b.wav
# ^C 将中止整个事情(也许它不再读取和处理 ^C 本身,现在收到一个 SIGINT 并死亡或杀死自己)。
play -q a.wav b.wav & pid=$!; sleep .5; kill -INT "$pid"
# 也杀死了整个事情。
(我在这里停止 - 不做进一步的测试......一直在陷入兔子洞。下一步是在 fg 中使用多个文件运行它并从另一个终端发送 -INT 。):)