Support libsndfile for WAV playback #859

Closed
Ghabry opened this Issue Apr 8, 2016 · 2 comments

Projects

None yet

2 participants

@Ghabry
Member
Ghabry commented Apr 8, 2016 edited

This is not really required for SDL, except for a few corner cases like 24 bit PCM but would be useful for non-SDL ports.

OpenAL already uses it.

  • Windows
  • macOS
  • Android
  • Wii
@Ghabry Ghabry added this to the 0.5.0 milestone Apr 8, 2016
@fdelapena
Member

👍 this would fix Ara Fell demo playback as it uses some 24-bit PCM Microsoft WAV files (unsupported by SDL).

@fdelapena
Member
fdelapena commented Apr 28, 2016 edited

Here is a proof of concept with loop support. Not widely tested, it fails with some wave file types yet (e.g. 96 khz 24 bit multichannel wave). Of course it needs some work for the audio format mapping (everything will play to 44100 in this test).

You can use sf_readf_* (note the "f") instead of sf_read_* to read frames (for 2 channels it reads twice) instead and adjust the len calculation.

#include "SDL.h"
#include "SDL_mixer.h"
#include <sndfile.h>
#include <stdio.h>

int musicPlaying;
SNDFILE *wavfile = NULL;
SF_INFO wavinfo;

void musicFinished() {
    printf("Music finished\n");
    /*Mix_HookMusic(NULL, NULL);*/
    /*musicPlaying = 0;*/
}

void play_wav(void *udata, Uint8 *stream, int len) {
    Uint8 *buffer = malloc(len);
    (void)udata; /* Unused yet, silence the compiler */

    if (!sf_read_short(wavfile, (short*)buffer, len / 2)) {
        sf_seek(wavfile, 0, SEEK_SET);
        musicFinished();
    }
    SDL_MixAudio(stream, buffer, len, SDL_MIX_MAXVOLUME);

    free(buffer);
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("Usage: %s filename.wav\n", argv[0]);
        return 1;
    }
    SDL_Init(SDL_INIT_AUDIO);
    Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);

    wavfile = sf_open(argv[1], SFM_READ, &wavinfo);
    sf_command(wavfile, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE);
    Mix_HookMusic(play_wav, NULL);

    musicPlaying = 1;
    while (musicPlaying) {
        SDL_Delay(200);
    }

    sf_close(wavfile);
    Mix_Quit();
    SDL_Quit();
    return 0;
}

Build with:

gcc wavplayer.c -o wavplayer `pkg-config --cflags --libs sndfile SDL2_mixer`
@carstene1ns carstene1ns closed this in #915 Jul 19, 2016
@Ghabry Ghabry modified the milestone: 0.5.0, 0.6.0 Jul 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment