将先前的答案移至该主题;以问题的形式提出,它将是:
我在用着查克特别是chuck.alsa
要实施Linux 的命令行多轨音频循环器。
很遗憾,该解决方案占用声卡,并且不能将其音频输出与其他应用程序(VLC、Firefox/Flash(youtube)...)混合,否则将使用 PulseAudio 来实现此目的。
如何使 ALSA 可执行文件chuck
通过 PulseAudio 路由其音频,以便可以将其音频输出与其他应用程序混合?
答案1
(移自这个答案):
好吧,我终于设法让 Linuxchuck
和 PulseAudio 一起工作了——这样我就可以chuck
从该帖子的接受答案与 VLC 或 Youtube Flash 一起,并自动混合它们各自的音频输出...所以,我要在这里记录下来..
Chuck 版本
请注意,接受的答案是在:
$ cat /etc/issue
Ubuntu 10.04.4 LTS \n \l
... 相关chuck
版本为:
$ chuck.alsa --version
chuck version: 1.2.0.8 (dracula)
exe target: linux (alsa)
http://chuck.cs.princeton.edu/
请注意,最新chuck
源版本(截至撰写本文时)是 1.3.1.3。chuck
需要在源代码中进行更改并重建,才能使其与 PulseAudio 一起工作。
1.2.0.8 版本和 1.3.1.3 版本之间存在一些差异chuck
,其中之一导致:
修改 chuck 1.3.1.3 的循环脚本
如果我们看看chuck
版本文件,我们可以注意到以下几点:
1.3.1.1
---
...
-(已修复)Windows 上的 Machine.add( ... ) 现在支持绝对路径中的 '\' 和 '/'(以前仅限 '\')。
原始调用loopsndbuf.ck
的格式如下:
chuck.alsa \
loopsndbuf.ck:/path/to/file1.wav:1.0 \
loopsndbuf.ck:/path/to/file2.wav:0.5 \ ...
...其中冒号:
被解析为chuck
脚本参数的分隔符;并且该列表中的第一个参数是chuck
被调用的文件名脚本(在本例中为loopsndbuf.ck
)。
随着 1.3.1.3 中的上述变化,冒号和斜杠的组合:/
现在会导致引擎跳过解析 - 因此整个loopsndbuf.ck:/path/to/file1.wav
被解释为chuck
脚本文件名 - 这当然会导致调用失败。
因此,原则上我们可以简单地在脚本调用中的:
和之间插入任何字符/
- 然后在脚本中解析它chuck
。不幸的是,到目前为止,chuck
脚本引擎似乎没有用于一般字符串解析的功能(请参阅[chuck-dev] charAt,字符串的子字符串);但是,它确实具有空白修剪功能(请init_class_string
参阅chuck_lang.cpp)。
因此,虽然我们不能使用任何字符作为分隔符 - 我们当然可以使用SPACE作为分隔符 - 这也迫使我们在脚本调用中引用参数。因此,调用本身(在 中loopchuck.sh
)需要更改为:
chuck.alsa \
loopsndbuf.ck:" /path/to/file1.wav":1.0 \
loopsndbuf.ck:" /path/to/file2.wav":0.5 \ ...
...并且loopsndbuf.ck
脚本需要if( me.args()...
改为:
if( me.args() ) me.arg(0).trim() => filename;
但好消息是,这样的调用对于 1.2.0.8 和 1.3.1.3 版本都有效chuck
。
chuck
从源代码构建
如上所述,最新的源代码发布(截至目前)chuck
chuck-1.3.1.3.tgz;我在 Ubuntu 10.04 机器上再次构建了它。
现在,在这个 Ubuntu 10.04 上,我已启用清晰的 PPA; 它提供了最新版本的,比如说,libogg-dev
从内部apt-get
- 但出于某种原因,不提供相应的版本libvorbis-dev
- 否则将被拉取libsndfile-dev
(这是构建的必要条件chuck
)。这就是为什么libvorbis-dev
必须下载匹配,并且软件包的安装必须分几个步骤进行,同时使用dpkg -i
和apt-get install
(参见下面的命令)。
除了build-essential
工具之外,我需要安装的软件包如下所示(可能我已经安装了其他必需品,所以请检查ChucK 手册:ch004_installation:Linux 构建和依赖项:在 Ubuntu 9.10 上编译 ChucK 和 miniAudicle)。下面是为 ALSA 构建的命令chuck
- 因为这是与最终 PulseAudio 更改相关的可执行文件:
# dependencies
wget http://ppa.launchpad.net/lucid-bleed/ppa/ubuntu/pool/main/libv/libvorbis/libvorbis-dev_1.3.1-1ubuntu1~ppa1~lucid1_i386.deb
sudo apt-get install bison flex libasound2-dev libogg-dev
sudo dpkg -i libvorbis-dev_1.3.1-1ubuntu1~ppa1~lucid1_i386.deb
sudo apt-get install libsndfile-dev
# source
wget http://chuck.cs.princeton.edu/release/files/chuck-1.3.1.3.tgz
tar xzvf chuck-1.3.1.3.tgz
cd chuck-1.3.1.3/src
make linux-alsa
# can copy executable at end manually (if not using `make install`):
sudo cp chuck /usr/bin/chuck.alsa-1.3.1.3
# cleanup dev libraries
sudo apt-get remove --purge bison flex libasound2-dev libsndfile-dev libogg-dev # also removes libvorbis-dev
#sudo dpkg -r libvorbis-dev # no need; dpkg: warning: ignoring request to remove libvorbis-dev which isn't installed
调试构建
如果您想要编译的调试版本chuck
(以便您可以使用来检查它gdb
);只需编辑makefile.alsa
(在chuck-1.3.1.3/src
目录中):注释掉第一行,然后创建一个新的,其中优化开关-O3
替换为调试开关-g
:
# CFLAGS+= -D__LINUX_ALSA__ -O3 -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__
CFLAGS+= -D__LINUX_ALSA__ -g -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__
...
...然后运行make clean
-最后再次运行make linux-alsa
。
chuck
在 ALSA 下使用 PulseAudio进行破解
首先,很高兴能回忆起 ALSA 和 PulseAudio 之间的关系 - 我喜欢如何同时使用 Pulse Audio 和 Alsa? - 询问 Ubuntu:
这个音频堆栈的简要解释有四个层次。
- 硬件。
- ALSA。
- 脉冲音频
- 应用程序。
其他相关页面ALSA 和 PulseAudio 有何关系? - 超级用户或者Pulseaudio 与 ALSA - Ubuntu 论坛(也可以看看脉冲音频图)。
其次,有两种方法可以从 ALSA 访问硬件设备 - 一种是通过接口hw:
,另一种是通过plughw:
界面。请注意,plughw:
界面为设备添加了自动采样率转换等功能 - 但本身并不提供不同应用程序音频的混合!有关更多信息,请参阅主题linux.alsa.devel - 回复:设备/子设备,hw:/plughw:。还请注意,在chuck
来源(源文件/RtAudio/RtAudio.cpp) 我们可以找:
// 我没有使用“插件”接口……行为不一致太多。
第三,除此之外,还有两种方法可以处理 ALSA 结构,如产出差异来自 ALSAaplay -l
和aplay -L
:
aplay -l
:硬件设备列表- 列出卡/设备/子设备
- -l, --list-devices:功能
device_list
- 功能循环遍历
snd_card_next
aplay -L
:输出设备列表 - 可能是硬件设备,也可能是 alsa 的许多插件(pulseaudio 插件、dmix 等等)- 列出输出(可按名称寻址)
- -L,--list-pcms:功能
pcm_list
- 1.0.22 aplay.c函数循环执行
snd_device_name_hint
;while1.0.8 aplay.c函数用途snd_config_search
值得注意的是,pulse
指定 PulseAudio 用法的输出名称仅出现在 中aplay -L
。问题是chuck
本质上适用于 ALSA 硬件设备(卡),因为chuck.alsa --probe
本质上返回与 相同的列表aplay -l
。因此,chuck
无法直接访问该设备 - 唯一可能的方法是将对代码中pulse
命名的设备的访问替换为名为 的设备。hw:X,Y
chuck
pulse
在chuck
代码中,只需要更改一个文件RtAudio.cpp
;以下是差异:
--- ./RtAudio/RtAudio.cpp.orig 2013-01-14 16:18:18.113645910 +0100
+++ ./RtAudio/RtAudio.cpp 2013-01-14 18:46:15.289672175 +0100
@@ -5657,7 +5699,8 @@
if ( result < 0 ) break;
if ( subdevice < 0 ) break;
if ( nDevices == device ) {
- sprintf( name, "hw:%d,%d", card, subdevice );
+ //~ sprintf( name, "hw:%d,%d", card, subdevice );
+ sprintf( name, "pulse");
snd_ctl_close( chandle );
goto foundDevice;
}
@@ -5696,6 +5739,7 @@
snd_pcm_t *phandle;
int openMode = SND_PCM_ASYNC;
+ printf( "pcm name %s\n", name);
result = snd_pcm_open( &phandle, name, stream, openMode );
if ( result < 0 ) {
if ( mode == OUTPUT )
请注意,使用此 hack,将完全通过 PulseAudio 进行路由,并且不会遵守chuck.alsa
通过 的设备设置。但是,在运行时,它还会导致 出现在 中:--dacN
chuck
gnome-volume-control
... 以及pavucontrol
。
请注意,在此模式下,该chuck
过程可能对 GUI 事件稍微敏感一些 - 例如,在滚动 Firefox 窗口等 GUI 密集型事件时音频会略有下降 - 但一般来说,PulseAudio 模式与直接 ALSA 模式一样好用(并且使用同样多的 CPU)。(在这台电脑上,我只需要chuck
播放这样的循环就可以了 - 但是,如果性能对您来说很重要,您最好尝试 JACK 路线。)
先前的 PulseAudio 重定向尝试
在找到上述技巧之前,我尝试了几种方法将 ALSA 音频“重定向”到 PulseAudio;不用说,由于上述原因,无法实现与其他应用程序音频的混合。但是,有一种方法可以做到这一点 - 路由aoss
音频alsa.oss
;不幸的是,它遭受了严重的音频丢失。
除了使用/etc/asound.conf 将 ALSA 重定向到 PulseAudio,下面是我尝试过的其他方法,它们(通常)无法与应用程序音频实现正确的混合(仅脚本的第一行相关内容loopchuck.sh
):
# via https://askubuntu.com/questions/8425/how-to-temporarily-disable-pulseaudio
# cannot mix, may need `pulseaudio --kill` to stop suspension
pasuspender -- chuck.alsa \
...
# stutters at first, but plays continuously
chuck.oss \
...
# via [How come aoss is better than padsp? - Ubuntu Forums](http://ubuntuforums.org/showthread.php?t=1259514)
# stutters a lot - but mixes audio!
padsp chuck.oss \
...
# stutters very little (upon gui updates though) - and mixes!
sudo apt-get install alsa-oss
aoss chuck.oss \
...
# via http://razor.occams.info/blog/2009/02/11/pulseaudio-sound-forwarding-across-a-network/
# plays OK, no mixing
ALSA_PCM_NAME=pulse chuck.alsa \
...
一个简单的 Python/Tkinter GUI
在我使用的 PC 上,loopchuck.sh
我没有键盘,所以我非常想要一个简单的 GUI 来启动和停止该过程(以及音频循环)。所以我编写了一个小 Python 脚本,tkGui_ShellScriptRunner.py,您可以将其放在与 相同的目录中loopchuck.sh
- 只需启用正确的scriptcall = ...
行 - 并chmod +x
在脚本之后,您可以通过双击其图标来调出此 GUI:
...您可以通过相应的按钮运行和停止脚本。