让 ALSA 程序 (ChucK) 与 Pulseaudio 协同工作?

让 ALSA 程序 (ChucK) 与 Pulseaudio 协同工作?

将先前的答案移至该主题;以问题的形式提出,它将是:

我在用着查克特别是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 -iapt-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

这个音频堆栈的简要解释有四个层次。

  1. 硬件。
  2. ALSA。
  3. 脉冲音频
  4. 应用程序。

其他相关页面ALSA 和 PulseAudio 有何关系? - 超级用户或者Pulseaudio 与 ALSA - Ubuntu 论坛(也可以看看脉冲音频图)。

其次,有两种方法可以从 ALSA 访问硬件设备 - 一种是通过接口hw:,另一种是通过plughw:界面。请注意,plughw:界面为设备添加了自动采样率转换等功能 - 但本身并不提供不同应用程序音频的混合!有关更多信息,请参阅主题linux.alsa.devel - 回复:设备/子设备,hw:/plughw:。还请注意,在chuck来源(源文件/RtAudio/RtAudio.cpp) 我们可以找:

// 我没有使用“插件”接口……行为不一致太多。

第三,除此之外,还有两种方法可以处理 ALSA 结构,如产出差异来自 ALSAaplay -laplay -L

值得注意的是,pulse指定 PulseAudio 用法的输出名称仅出现在 中aplay -L。问题是chuck本质上适用于 ALSA 硬件设备(卡),因为chuck.alsa --probe本质上返回与 相同的列表aplay -l。因此,chuck无法直接访问该设备 - 唯一可能的方法是将对代码中pulse命名的设备的访问替换为名为 的设备。hw:X,Ychuckpulse

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通过 的设备设置。但是,在运行时,它还会导致 出现在 中:--dacNchuckgnome-volume-control

gnome-音量控制

... 以及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:

图形用户界面

...您可以通过相应的按钮运行和停止脚本。

相关内容