Что такое легкая кросс-платформа WAV, играющая в библиотеку?

Я ищу легкий способ сделать мою программу (написанную на C) возможностью воспроизведения аудиофайлов в Windows или Linux. В настоящее время я использую собственные вызовы Windows, которые по существу представляют собой только один вызов, которому передается имя файла. Мне хотелось бы что-то подобное, что работает на linux.

Аудиофайлы: Microsoft PCM, Single channel, 22Khz

Любые предложения?

Ответ 1

Так как я также ищу ответ на вопрос, я немного научился, и я не нашел простой (простой, как вызов одной функции) способ воспроизведения аудиофайла. Но с некоторыми строками кода это возможно даже в переносном режиме с использованием уже упомянутого portaudio и libsndfile (LGPL).

Вот небольшой тестовый пример, который я написал для тестирования обеих библиотек:


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

Некоторые примечания к примеру. Неправильная практика - выполнять загрузку данных внутри обратного вызова потока, но внутри собственной загрузочной нити. Если вам нужно воспроизвести несколько аудиофайлов, это становится еще более сложным, потому что не все серверы portaudio поддерживают несколько потоков для одного устройства, например, OSS-бэкэнд не работает, но сервер ALSA делает это. Я не знаю, как ситуация на окнах. Поскольку все ваши входные файлы имеют один и тот же тип, вы можете смешивать их самостоятельно, что усложняет код немного больше, но тогда у вас также будет поддержка OSS. Если бы у вас были разные частоты дискретизации или количество каналов, стало бы очень сложно.

Итак, если вы не хотите одновременно воспроизводить несколько файлов, это может быть решением или, по крайней мере, началом для вас.

Ответ 2

SDL_Mixer, хотя и не очень легкий, имеет простой интерфейс для воспроизведения файлов WAV. Я считаю, что SDL, SDL_Mixer также LGPL.

OpenAL - это еще одна кросс-платформенная аудио-библиотека, которая больше ориентирована на 3D-звук.

Еще одна библиотека аудио с открытым исходным кодом, которую вы можете проверить, это PortAudio

Ответ 3

Я использовал OpenAL для воспроизведения файлов wav в качестве предупреждений/предупреждений в системе управления воздушным движением

Преимущества, которые я нашел,

  • это кросс-платформа
  • работает с C (и другими, но ваш вопрос о C)
  • легкий вес
  • хорошая документация, доступная в Интернете.
  • Лицензия - это LGPL, поэтому вы вызываете API без проблем с лицензией.

Ответ 4

Вы можете попробовать с этим: libao

Ответ 6

Вы также можете попробовать Audiere. Последний релиз датирован 2006 годом, но он открыт с открытым исходным кодом и лицензирован под LGPL.

Ответ 7

Я использовал irrKlang!

"irrKlang - это кросс-платформенная звуковая библиотека для С++, С# и всех языков .NET"

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