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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:45:06  来源:igfitidea点击:

What is a lightweight cross platform WAV playing library?

cwindowslinuxaudiocross-platform

提问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

我发现的优点是

  1. it is cross platform
  2. works with C (and others but your question is about 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
  1. 它是跨平台的
  2. 与 C 一起工作(和其他人,但你的问题是关于 C)
  3. 轻的
  4. 网上有很好的文档
  5. 许可证是 LGPL,所以你调用 API 没有许可证问题

回答by Marc

You can try with this one: libao

你可以试试这个:libao

回答by AShelly

I like FMOD. The licenseis free for personal use, and very reasonable for small shareware or commercial projects

我喜欢FMOD。该许可证可供个人免费使用,对于小型共享软件或商业项目非常合理

回答by pt2ph8

You could also try Audiere. The last release is dated 2006, but it is open-source and licensed under the LGPL.

你也可以试试Audiere。最后一个版本发布于 2006 年,但它是开源的,并在 LGPL 下获得许可。

回答by Emadpres

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/