SoX:我可以同时生成声音吗?

问题描述 投票:0回答:3

我使用 SoX 来生成这个声音:

$ play -n synth 1 pluck E3 repeat 2

我设法在一个新的终端选项卡中同时播放另一个模式,比如说

$ play -n synth 1.5 pluck C3 repeat 2
。有没有办法在同一个 bash 脚本中同时播放这两种模式?

bash sox
3个回答
6
投票

这将实现您所需要的,在左声道上播放 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

...多个合成器效果可以级联以产生更复杂的波形;...


2
投票

为了解决在同一终端中同时运行两个

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; }

0
投票

纠正您提出的几点:

  1. 后台作业可以写入终端完全正常,不会被停止(挂起)。
  2. 后台作业将被暂停,如果他们尝试从终端读取
  3. 因此:
    play ..stuff.. </dev/null &
    足以防止其停止。
  4. 请注意,
    -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 。):)

© www.soinside.com 2019 - 2024. All rights reserved.