当前位置:  开发笔记 > 运维 > 正文

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

如何解决《什么是轻量级跨平台WAV播放库?》经验,为你挑选了1个好方法。

我正在寻找一种轻量级的方法来使我的程序(用C语言编写)能够在Windows或Linux上播放音频文件.我目前正在使用Windows本机调用,这实际上只是一个传递文件名的调用.我想在linux上运行类似的东西.

音频文件是Microsoft PCM,单通道,22Khz

有什么建议?



1> quinmars..:

由于我也在寻找问题的答案,我做了一些研究,我没有找到任何简单的(简单的称为调用一个函数)方式来播放音频文件.但是使用一些代码行,甚至可以使用已经提到的portaudio和libsndfile(LGPL)以便携方式.

这是我为测试两个库而编写的一个小测试用例:

#include 
#include 

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;
}

这个例子的一些注释.在流回调中进行数据加载不是一个好习惯,而是在自己的加载线程中.如果您需要播放多个音频文件,则变得更加困难,因为并非所有portaudio后端都支持一个设备的多个流,例如OSS后端不支持,但ALSA后端支持多个.我不知道Windows的情况如何.由于您的所有输入文件都是相同的类型,您可以自己混合它们,这会使代码复杂化,但是您也支持OSS.如果您的采样率或通道数也不同,那将变得非常困难.

因此,如果您不想同时播放多个文件,这可能是一个解决方案,或者至少是一个开始.

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有