Playing a sound with portaudio and libsndfile

Low level audio implementation.

This is a low-level audio playback implementation using libsndfile to read audio data from a .wav file and PortAudio to stream the audio to the default output device. It includes memory management, a stream callback function, and basic file I/O error handling.

With libsndfile I can easily decode wav files.

  soundData->soundfile = sf_open("D:/Coding/C++/Test_Portaudio_Libsndfile/assets/Audio_01.wav", 
                                 SFM_READ, 
                                 &soundData->info);
      if (soundData->soundfile == NULL) {
          printf("Error: Couldn't open the soundfile.\n");
          free(soundData);
          return EXIT_FAILURE;
      }

A custom callback is created to pass the wav data to the output buffer.

  static int myCallback(const void* input, void* output, unsigned long frameCount,
    const PaStreamCallbackTimeInfo* timeInfo,
    PaStreamCallbackFlags statusFlags, void* userData)
  {
    SoundData* data = (SoundData*)userData;
    float* out = (float*)output;
    (void)input;
    
    unsigned long totalSamples = frameCount * data->info.channels;

    sf_count_t readSamples = sf_read_float(data->soundfile, out, totalSamples);

    if (readSamples < totalSamples) 
    {
        for (sf_count_t i = readSamples; i < totalSamples; i++) 
        {
            out[i] = 0.0f; 
        }
        return paComplete; 
    }

    return paContinue;   
  }

Result


You can find the code in my repo here!