Thanks for the reply!
Yes I want to process the file before the “realtime” loop, so to say. Yes, its possible to do things in the DAW, but I want that process to react to game elements, ie the user can change the stretch ratio. If I do this in the DAW, the stretch ratio would be constant.
So for best quality stretching rubberband needs to access the whole audio file, which obviosly is not possible in the realtime flow where you only get a fraction of the audio at a time.
I’m looking at doing this using fmod_codec. The stretch ratio is passed as user data and when the file is opened and read ,I stretch the file with that amount. The stretch ratio wont be possible to change in realtime, but it can change for each new open and read. So each time you press play you can have a new ratio.
Im looking at the raw codec example, but what I cant figure out is how to process the audio in the read callback. The example supplied doesnt do any processing. When I try changing values in the buffer, it either crash or does nothing. This is what I have right now:
int ibs = 1024;
size_t channels = 2;
float* fbuf;
float** ibuf;
int frame = 0;
int percent = 0;
size_t countIn = 0, countOut = 0;
const float** ptrs = new const float* [2];
float* bufL = new float[8192 * 4];
float* bufR = new float[8192 * 4];
float** tmp = new float* [2];
unsigned int length = 0;
FMOD_RESULT F_CALLBACK rawread(FMOD_CODEC_STATE *codec, void *buffer, unsigned int size, unsigned int *read)
{
RubberBand::RubberBandStretcher* m_stretcher = (RubberBand::RubberBandStretcher *) codec->plugindata;
channels = 2;
ptrs[0] = bufL;
ptrs[1] = bufR;
length = 1024;
codec->fileread(codec->filehandle, buffer, size, &length, 0);
length = 1024;// std::min(1024, (int)*read);
// De-iterleave
if (length > 0)
{
for (int i = 0; i < length - 1; i++) {
bufL[i] = ((float*)buffer)[0 + i * channels];
bufR[i] = ((float*)buffer)[1 + i * channels];
}
m_stretcher->process(ptrs, length, 0);
int avail = m_stretcher->available();
if (avail > 0) {
m_stretcher->retrieve(tmp, avail);
// Re-interleave
for (int i = 0; i < avail - 1; i++) {
((float*)buffer)[0 + i * channels] = tmp[0][i];
((float*)buffer)[1 + i * channels] = tmp[1][i];
}
}
}
read = &length;
return FMOD_OK;//
}