bool CDVDPlayerResampler::Retrieve(DVDAudioFrame &audioframe, double &pts) { //check if nr of channels changed so we can allocate new buffers if necessary CheckResampleBuffers(audioframe.channel_count); //value to divide samples by to get them into -1.0:1.0 range float scale = (float)(1 << (audioframe.bits_per_sample - 1)); int nrframes = audioframe.size / audioframe.channel_count / (audioframe.bits_per_sample / 8); //if we don't have enough in the samplebuffer, return false if (nrframes > m_bufferfill) { return false; } //use the pts of the first fresh value in the samplebuffer pts = m_ptsbuffer[0]; //add from samplebuffer to audioframe float* inputptr = m_buffer; int16_t* outputptr = (int16_t*)audioframe.data; for (int i = 0; i < nrframes * m_nrchannels; i++) *outputptr++ = MathUtils::round_int(Clamp(*inputptr++ * scale, scale * -1.0f, scale - 1.0f)); m_bufferfill -= nrframes; //shift old data to the beginning of the buffer memmove(m_buffer, m_buffer + (nrframes * m_nrchannels), m_bufferfill * m_nrchannels * sizeof(float)); memmove(m_ptsbuffer, m_ptsbuffer + nrframes, m_bufferfill * sizeof(double)); return true; }
void CDVDPlayerResampler::Add(DVDAudioFrame &audioframe, double pts) { //check if nr of channels changed so we can allocate new buffers if necessary CheckResampleBuffers(audioframe.channel_count); //value to divide samples by to get them into -1.0:1.0 range float scale = (float)(1 << (audioframe.bits_per_sample - 1)); int nrframes = audioframe.size / audioframe.channel_count / (audioframe.bits_per_sample / 8); //resize sample buffer if necessary //we want the buffer to be large enough to hold the current frames in it, //the number of frames needed for libsamplerate's input //and the maximum number of frames libsamplerate might generate, times 2 for safety ResizeSampleBuffer(m_bufferfill + nrframes + nrframes * MathUtils::round_int(m_ratio + 0.5) * 2); //assign samplebuffers m_converterdata.input_frames = nrframes; m_converterdata.output_frames = m_buffersize - m_bufferfill - m_converterdata.input_frames; //output buffer starts at the place where the buffer doesn't hold samples m_converterdata.data_out = m_buffer + m_bufferfill * m_nrchannels; //intput buffer is a block of data at the end of the buffer m_converterdata.data_in = m_converterdata.data_out + m_converterdata.output_frames * m_nrchannels; //add samples to the resample input buffer int16_t* inputptr = (int16_t*)audioframe.data; float* outputptr = m_converterdata.data_in; for (int i = 0; i < nrframes * m_nrchannels; i++) *outputptr++ = (float)*inputptr++ / scale; //resample m_converterdata.src_ratio = m_ratio; src_set_ratio(m_converter, m_ratio); src_process(m_converter, &m_converterdata); //calculate a pts for each sample for (int i = 0; i < m_converterdata.output_frames_gen; i++) { m_ptsbuffer[m_bufferfill] = pts + i * (audioframe.duration / (double)m_converterdata.output_frames_gen); m_bufferfill++; } }