Closed wictorsson closed 1 year ago
You seem to to be calling the "callback" function with individual chunks of some single stream of audio. Within the callback you are calling src_new
which creates a new SRC_STATE
object and then you are deleting it before the callback returns.
The problem is that you are failing to persist the SRC_STATE
object between calls to the callback instead of creating a new one for each call.
Psuedo code:
src_state = src_new (.....);
for loop :
callback (src_state, ....);
src_delete (src_state);
You seem to to be calling the "callback" function with individual chunks of some single stream of audio. Within the callback you are calling
src_new
which creates a newSRC_STATE
object and then you are deleting it before the callback returns.The problem is that you are failing to persist the
SRC_STATE
object between calls to the callback instead of creating a new one for each call.Psuedo code:
src_state = src_new (.....); for loop : callback (src_state, ....); src_delete (src_state);
Ok, thanks for checking but I am still getting zipper noise (discontinuity) in the output. I changed the code, sending a pointer from main function into the callback function instead, but now I am getting the same result even when the ratio is set to 1.
int callback(void *outputBuffer, void *input_buffer, unsigned int nBufferFrames,
double streamTime, RtAudioStreamStatus status, void *userData)
{
// Get the input and output buffers from the user data
float *output_buffer = (float *)outputBuffer;
// Get the sample rate converter state from the user data
SRC_STATE *state = (SRC_STATE *)userData;
// Set up the sample rate conversion data
SRC_DATA src_data;
src_data.src_ratio = 48000.0 / 44100.0;
src_data.end_of_input = 0;
// Allocate a buffer to hold the audio frames
float *inbuffer = (float *)malloc(nBufferFrames * 4.0 * sfinfo.channels * sizeof(float));
float *outbuffer = (float *)malloc(nBufferFrames * 4.0 * sfinfo.channels * sizeof(float));
// Loop until we reach the end of the output buffer
long output_frames_remaining = nBufferFrames * sfinfo.channels;
while (output_frames_remaining > 0)
{
// Read a chunk of audio from the input file
sf_count_t input_frames_read = sf_read_float(file, inbuffer, nBufferFrames * sfinfo.channels);
// Set up the sample rate conversion data
src_data.data_in = inbuffer;
src_data.data_out = outbuffer;
src_data.input_frames = input_frames_read;
src_data.output_frames = input_frames_read * src_data.src_ratio;
// Check if we have reached the end of the input file
if (input_frames_read < nBufferFrames * sfinfo.channels)
{
src_data.end_of_input = 1;
}
// Perform sample rate conversion
int error = src_process(state, &src_data);
if (error != 0)
{
// Handle error
}
// Copy the generated frames to the output buffer
size_t copy_frames = std::min(src_data.output_frames_gen, output_frames_remaining);
for (size_t i = 0; i < copy_frames; i++)
{
output_buffer[i] = static_cast<float>(src_data.data_out[i]);
}
output_buffer += copy_frames;
output_frames_remaining -= copy_frames;
}
// Update the play position
playPosition = dac.getStreamTime();
// Clean up
free(inbuffer);
free(outbuffer);
return 0;
}```
You seem to to be calling the "callback" function with individual chunks of some single stream of audio. Within the callback you are calling
src_new
which creates a newSRC_STATE
object and then you are deleting it before the callback returns.The problem is that you are failing to persist the
SRC_STATE
object between calls to the callback instead of creating a new one for each call.Psuedo code:
src_state = src_new (.....); for loop : callback (src_state, ....); src_delete (src_state);
Solved! Followed these instructions and I also needed to calculate the amount of input frames to get the expected output frames to be used within the callback in RTaudio.
Hi, I'm trying to do samplerate conversion in the callback function. The conversion works but I am getting zipper noise. I guess something is wrong with the input/output buffers but just can't figure it out. Since I am in the callback function I assume src_process is the correct way to use it. Playing files without libsamplerate or setting the ratio to 1 plays the audio without any problems. I am using RTaudio, libsndfile and libsamplerate