c++bufferwavfile-writinglibsndfile

WAV writing function can't sync after writing to stereo


I'm trying to use the following function to create a 2-channel stereo .wav file from an interleaved input buffer. The function works fine when slightly modified to write to a 1-channel mono file, but in its current state it returns an exception thrown error:

void audiowrite(double* inputBuffer, int bufferLength, int fs, std::string outputFileLocation){
    SF_INFO info;
    info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
    info.channels = 2;
    info.samplerate = fs;

    SNDFILE* sndFile = sf_open(outputFileLocation.c_str(), SFM_WRITE, &info);

    sf_writef_double(sndFile, inputBuffer, bufferLength);

    sf_write_sync(sndFile); //Exception thrown - access violation reading location
    sf_close(sndFile);
}

I am almost certain the issue is somewhere within this function, as changing the input buffer to different values doesn't change anything. If anyone would be able to see what is immediately wrong with this function, I would appreciate it.


Solution

  • My best guess and the classic mistake with this function is that inputBuffer is too short.

    When you use sf_writef_double the unit of the third argument is a frame (i.e. sample*nb_channels).

    From documentation:

    For the frames-count functions, the array is expected to be large enough to hold a number of items equal to the product of frames and the number of channels.

    You can fix it by either :

    double inputBuffer[bufferLength];
    ...
    void audiowrite(double* inputBuffer, int bufferLength, int fs, std::string outputFileLocation){
    ...
      sf_writef_double(sndFile, inputBuffer, bufferLength/2); // Unit is frame
    ...
    }
    

    Or

    double inputBuffer[bufferLength];
    ...
    void audiowrite(double* inputBuffer, int bufferLength, int fs, std::string outputFileLocation){
    ...
      sf_write_double(sndFile, inputBuffer, bufferLength); // Remove the 'f' unit is sample not frame
    ...
    }
    

    That would also explain why the bug doesn't happen with mono-channel because in this case, frame = sample.