windows 什么是轻量级跨平台WAV播放库?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/379353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is a lightweight cross platform WAV playing library?
提问by Loki
I'm looking for a lightweight way to make my program (written in C) be able to play audio files on either windows or linux. I am currently using windows native calls, which is essentially just a single call that is passed a filename. I would like something similar that works on linux.
我正在寻找一种轻量级的方法来使我的程序(用 C 编写)能够在 windows 或 linux 上播放音频文件。我目前正在使用 Windows 本机调用,它本质上只是一个传递文件名的调用。我想要类似的东西在 linux 上工作。
The audio files are Microsoft PCM, Single channel, 22Khz
音频文件为 Microsoft PCM, Single channel, 22Khz
Any Suggestions?
有什么建议?
采纳答案by quinmars
Since I'm also looking for an answer for question I did a bit of research, and I haven't find any simple (simple like calling one function) way to play an audio file. But with some lines of code, it is possible even in a portable way using the already mentioned portaudio and libsndfile (LGPL).
因为我也在寻找问题的答案,所以我做了一些研究,但我没有找到任何简单的(就像调用一个函数一样简单)播放音频文件的方法。但是通过一些代码行,甚至可以使用已经提到的 portaudio 和 libsndfile (LGPL) 以可移植的方式实现。
Here is a small test case I've written to test both libs:
这是我编写的一个小测试用例来测试两个库:
#include <portaudio.h>
#include <sndfile.h>
static int
output_cb(const void * input, void * output, unsigned long frames_per_buffer,
const PaStreamCallbackTimeInfo *time_info,
PaStreamCallbackFlags flags, void * data)
{
SNDFILE * file = data;
/* this should not actually be done inside of the stream callback
* but in an own working thread
*
* Note although I haven't tested it for stereo I think you have
* to multiply frames_per_buffer with the channel count i.e. 2 for
* stereo */
sf_read_short(file, output, frames_per_buffer);
return paContinue;
}
static void
end_cb(void * data)
{
printf("end!\n");
}
#define error_check(err) \
do {\
if (err) { \
fprintf(stderr, "line %d ", __LINE__); \
fprintf(stderr, "error number: %d\n", err); \
fprintf(stderr, "\n\t%s\n\n", Pa_GetErrorText(err)); \
return err; \
} \
} while (0)
int
main(int argc, char ** argv)
{
PaStreamParameters out_param;
PaStream * stream;
PaError err;
SNDFILE * file;
SF_INFO sfinfo;
if (argc < 2)
{
fprintf(stderr, "Usage %s \n", argv[0]);
return 1;
}
file = sf_open(argv[1], SFM_READ, &sfinfo);
printf("%d frames %d samplerate %d channels\n", (int)sfinfo.frames,
sfinfo.samplerate, sfinfo.channels);
/* init portaudio */
err = Pa_Initialize();
error_check(err);
/* we are using the default device */
out_param.device = Pa_GetDefaultOutputDevice();
if (out_param.device == paNoDevice)
{
fprintf(stderr, "Haven't found an audio device!\n");
return -1;
}
/* stero or mono */
out_param.channelCount = sfinfo.channels;
out_param.sampleFormat = paInt16;
out_param.suggestedLatency = Pa_GetDeviceInfo(out_param.device)->defaultLowOutputLatency;
out_param.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(&stream, NULL, &out_param, sfinfo.samplerate,
paFramesPerBufferUnspecified, paClipOff,
output_cb, file);
error_check(err);
err = Pa_SetStreamFinishedCallback(stream, &end_cb);
error_check(err);
err = Pa_StartStream(stream);
error_check(err);
printf("Play for 5 seconds.\n");
Pa_Sleep(5000);
err = Pa_StopStream(stream);
error_check(err);
err = Pa_CloseStream(stream);
error_check(err);
sf_close(file);
Pa_Terminate();
return 0;
}
Some notes to the example. It is not good practice to do the data loading inside of the stream callback, but inside an own loading thread. If you need to play several audio files it becomes even more difficult, because not all portaudio backends support multiple streams for one device, for example the OSS backend doesn't, but the ALSA backend does. I don't know how the situation is on windows. Since all your input files are of the same type you could mix them on you own, which complicates the code a bit more, but then you'd have also support for OSS. If you would have also different sample rates or number of channels, it'd become very difficult.
示例的一些注释。在流回调内部进行数据加载不是一个好习惯,而是在自己的加载线程中进行。如果您需要播放多个音频文件,那就变得更加困难了,因为并非所有 portaudio 后端都支持一台设备的多个流,例如 OSS 后端不支持,但 ALSA 后端支持。我不知道 windows 上的情况如何。由于您所有的输入文件都是相同类型的,您可以自己混合它们,这会使代码更加复杂,但是您也可以支持 OSS。如果您还有不同的采样率或通道数,那将变得非常困难。
So If you don't want to play multiple files at the same time, this could be a solution or at least a start for you.
因此,如果您不想同时播放多个文件,这可能是一个解决方案,或者至少是您的一个开始。
回答by codelogic
SDL_Mixer, although not very lightweight, does have a simple interface to play WAV files. I believe, like SDL, SDL_Mixer is also LGPL.
SDL_Mixer虽然不是很轻量级,但确实有一个简单的界面来播放 WAV 文件。我相信,像SDL一样, SDL_Mixer 也是 LGPL。
OpenALis another cross platform audio library that is more geared towards 3D audio.
OpenAL是另一个更适合 3D 音频的跨平台音频库。
Yet another open source audio library that you might want to check it out is PortAudio
您可能想查看的另一个开源音频库是PortAudio
回答by hhafez
I've used OpenAL to play wav files as alerts/warnings in an Air Traffic Control system
我已经使用 OpenAL 在空中交通管制系统中播放 wav 文件作为警报/警告
The advantages I've found are
我发现的优点是
- it is cross platform
- works with C (and others but your question is about C)
- light weight
- good documentation available on the web
- the license is LGPL so you call the API with no license problems
- 它是跨平台的
- 与 C 一起工作(和其他人,但你的问题是关于 C)
- 轻的
- 网上有很好的文档
- 许可证是 LGPL,所以你调用 API 没有许可证问题
回答by AShelly
回答by pt2ph8
回答by Emadpres
I used irrKlang !
我使用了 irrKlang !
"irrKlang is a cross platform sound library for C++, C# and all .NET languages"
“irrKlang 是 C++、C# 和所有 .NET 语言的跨平台声音库”