一种linux声音解决方案ALSA+pauseaudio

本文介绍了Linux下的ALSA声音体系,作为声卡驱动的替代方案,以及PulseAudio作为声音服务器的角色。PulseAudio解决了ALSA的混音和声卡独占问题,但也存在部分软件不支持的情况。使用PulseAudio可以降低MPD的CPU占用,并且具备跨平台特性。Music Player Daemon(MPD)是一个强大的服务器端音乐播放器,需要配合客户端进行操作。

ALSA(高级Linux声音体系)是为声卡提供驱动的Linux内核组件,以替代原先的OSS(开放声音系统).这两个是系统发出声音最低层的软件系统,可以视为(或者就是)驱动.

PulseAudioESD是两个声音服务器,简单说,软件要发声就先发消息给声音服务器,然后声音服务器经过处理(主要是多条音频流的混音),然后发给驱动控制声音设备发出声音.

选用pulseaudio+alsa的好处和坏处,好处就是解决混音和声卡独占问题,缺点就是有些软件(极其个别)还不支持

 

声音服务器并不是必须的,你可以跳过esdpulseaudio直接控制alsaoss,只是没有了单独的声音控制以及混音功能.有的同学说了,不对啊,我就能混音,其实那是因为alsa自带了一个很简单的混音器dmix,这也是混音常常出问题,常常声卡独占的原因.用 pulseaudio 代替 alsa 自带的 dmix 可以明显减小 mpd 的 cpu 占用。


ALSA不同,PulseAudio可以在多个操作系统中运行,包括其他的POSIX平台和微软的Windows。也就是说如果你建立一个是用PulseAudio的应用程序而非ALSA,把这个应用移植到另一个平台会很容易。

 

Music Player Daemon (MPD)是一个小巧的,功能强大的服务器端音乐播放器。在其网络协议下,通过添加插件和音乐库可以播放大量格式的音乐文件。除了播放之外,他还能管理播放列表,管理音乐数据库。由于是后台进程,所以需要一个单独的客户端。


Linux系统下,使用C++ALSA库通过`plughw`设备播放音频是一种常见的做法,尤其适用于需要直接与硬件交互但又希望保留一定灵活性的场景。`plughw`设备允许应用程序使用软件插件来处理那些硬件不支持的格式或配置,从而实现更广泛的兼容性。 要通过`plughw`设备播放音频,首先需要初始化PCM(Pulse Code Modulation)设备,并设置适当的硬件参数,包括访问模式、数据格式、采样率、通道数等。以下是一个基本的示例代码,展示了如何使用ALSA库进行音频播放: ```cpp #include <alsa/asoundlib.h> #include <iostream> int main() { snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int rate = 44100; int channels = 2; snd_pcm_uframes_t frames = 32; // 打开PCM设备 if (snd_pcm_open(&handle, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0) < 0) { std::cerr << "无法打开PCM设备" << std::endl; return -1; } // 分配硬件参数对象 snd_pcm_hw_params_alloca(&params); // 初始化硬件参数 if (snd_pcm_hw_params_any(handle, params) < 0) { std::cerr << "无法初始化硬件参数" << std::endl; return -1; } // 设置访问模式为交错模式 if (snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { std::cerr << "无法设置访问模式" << std::endl; return -1; } // 设置数据格式为16位小端 if (snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE) < 0) { std::cerr << "无法设置数据格式" << std::endl; return -1; } // 设置采样率为44100Hz if (snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0) < 0) { std::cerr << "无法设置采样率" << std::endl; return -1; } // 设置通道数为立体声 if (snd_pcm_hw_params_set_channels(handle, params, channels) < 0) { std::cerr << "无法设置通道数" << std::endl; return -1; } // 设置周期大小 if (snd_pcm_hw_params_set_period_size_near(handle, params, &frames, 0) < 0) { std::cerr << "无法设置周期大小" << std::endl; return -1; } // 应用硬件参数 if (snd_pcm_hw_params(handle, params) < 0) { std::cerr << "无法应用硬件参数" << std::endl; return -1; } // 播放音频数据 short buffer[frames * channels]; for (int i = 0; i < sizeof(buffer)/sizeof(buffer[0]); ++i) { buffer[i] = 0; // 填充静音数据 } for (int i = 0; i < 100; ++i) { // 播放100个周期 if (snd_pcm_writei(handle, buffer, frames) < 0) { std::cerr << "写入音频数据失败" << std::endl; break; } } // 关闭PCM设备 snd_pcm_close(handle); return 0; } ``` 上述代码中,首先通过`plughw:0,0`打开了默认的播放设备,并设置了交错模式、16位小端格式、44100Hz采样率以及立体声音频输出[^5]。接着,分配了一个缓冲区并填充了静音数据,然后循环写入音频数据以播放音频。 需要注意的是,在实际应用中,通常会从文件或其他来源读取音频数据,并确保数据格式与所设置的硬件参数相匹配。此外,错误处理是关键,必须仔细检查每个函数调用的结果,以便及时发现并处理可能出现的问题。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值