由于我也在寻找问题的答案,因此我做了一些研究,但没有找到播放音频文件的任何简单(类似于调用一个函数的简单方法)。但是使用一些代码行,甚至可以使用已经提到的portaudio和libsndfile(LGPL)以可移植的方式实现。
这是我为测试两个库而编写的一个小测试用例:
#include <portaudio.h>#include <sndfile.h>static intoutput_cb(const void * input, void * output, unsigned long frames_per_buffer, const PaStreamCallbackTimeInfo *time_info, PaStreamCallbackFlags flags, void * data){ SNDFILE * file = data; sf_read_short(file, output, frames_per_buffer); return paContinue;}static voidend_cb(void * data){ printf("end!n");}#define error_check(err) do { if (err) { fprintf(stderr, "line %d ", __LINE__); fprintf(stderr, "error number: %dn", err); fprintf(stderr, "nt%snn", Pa_GetErrorText(err)); return err; } } while (0)intmain(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 channelsn", (int)sfinfo.frames, sfinfo.samplerate, sfinfo.channels); err = Pa_Initialize(); error_check(err); out_param.device = Pa_GetDefaultOutputDevice(); if (out_param.device == paNoDevice) { fprintf(stderr, "Haven't found an audio device!n"); return -1; } 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。如果您还有不同的采样率或通道数,则将变得非常困难。
因此,如果您不想同时播放多个文件,这可能是一个解决方案,或者至少是您的一个开始。



