简体   繁体   English

什么是轻量级跨平台WAV播放库?

[英]What is a lightweight cross platform WAV playing library?

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. 我正在寻找一种轻巧的方法来使我的程序(用C语言编写)能够在Windows或Linux上播放音频文件。 I am currently using windows native calls, which is essentially just a single call that is passed a filename. 我目前正在使用Windows本机调用,这实际上只是传递文件名的单个调用。 I would like something similar that works on linux. 我想要在Linux上也可以使用的类似软​​件。

The audio files are Microsoft PCM, Single channel, 22Khz 音频文件是Microsoft PCM,单通道,22Khz

Any Suggestions? 有什么建议么?

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. 如果您需要播放多个音频文件,这将变得更加困难,因为并非所有portaudio后端都支持一个设备的多个流,例如OSS后端不支持,而ALSA后端则支持。 I don't know how the situation is on windows. 我不知道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. 由于所有输入文件都是相同的类型,因此您可以自己将它们混合使用,这会使代码更加复杂,但同时您还支持OSS。 If you would have also different sample rates or number of channels, it'd become very difficult. 如果您还有不同的采样率或通道数,则将变得非常困难。

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. 因此,如果您不想同时播放多个文件,这可能是一个解决方案,或者至少是您的一个开始。

SDL_Mixer , although not very lightweight, does have a simple interface to play WAV files. SDL_Mixer虽然不是很轻巧,但确实具有播放WAV文件的简单界面。 I believe, like SDL , SDL_Mixer is also LGPL. 我相信,像SDL一样,SDL_Mixer也是LGPL。

OpenAL is 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

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 我发现的优势是

  1. it is cross platform 这是跨平台
  2. works with C (and others but your question is about C) 与C一起工作(以及其他人,但您的问题与C有关)
  3. light weight 重量轻
  4. good documentation available on the web 网上有不错的文档
  5. the license is LGPL so you call the API with no license problems 许可证是LGPL,因此您调用API时不会出现许可证问题

您可以尝试以下一种: libao

I used irrKlang ! 我用了irrKlang!

"irrKlang is a cross platform sound library for C++, C# and all .NET languages" “ irrKlang是针对C ++,C#和所有.NET语言的跨平台声音库”

http://www.ambiera.com/irrklang/ http://www.ambiera.com/irrklang/

I like FMOD . 我喜欢FMOD The license is free for personal use, and very reasonable for small shareware or commercial projects 许可证免费供个人使用,对于小型共享软件或商业项目非常合理

You could also try Audiere . 您也可以尝试Audiere The last release is dated 2006, but it is open-source and licensed under the LGPL. 最新版本发布于2006年,但是它是开源的,并根据LGPL许可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM