HRESULT CChannelMixer::FlushStream() { HRESULT hr = S_OK; CAutoLock lock (&m_csOutputSample); if (m_pNextOutSample) { hr = OutputNextSample(); if (FAILED(hr)) Log("CChannelMixer::FlushStream OutputNextSample failed with: 0x%08x", hr); } return hr; }
void CTimeStretchFilter::OutputSample(bool bForce) { if (m_pNextOutSample) { UINT32 sampleLen = m_pNextOutSample->GetActualDataLength(); if (bForce || (sampleLen + m_pOutputFormat->Format.nBlockAlign > DEFAULT_OUT_BUFFER_SIZE)) { HRESULT hr = OutputNextSample(); m_rtInSampleTime += sampleLen / m_pOutputFormat->Format.nBlockAlign * UNITS / m_pOutputFormat->Format.nSamplesPerSec; if (FAILED(hr)) Log("CTimeStretchFilter::timestretch thread OutputNextSample failed with: 0x%08x", hr); } } }
void CTimeStretchFilter::OutputSample(bool bForce) { if (m_pNextOutSample) { UINT32 sampleLen = m_pNextOutSample->GetActualDataLength(); if (bForce || (sampleLen + m_pOutputFormat->Format.nBlockAlign > m_nOutBufferSize)) { HRESULT hr = OutputNextSample(); m_rtInSampleTime += (sampleLen * UNITS) / (m_pOutputFormat->Format.nBlockAlign * m_pOutputFormat->Format.nSamplesPerSec); if (FAILED(hr)) Log("CTimeStretchFilter::timestretch thread OutputNextSample failed with: 0x%08x", hr); } } }
HRESULT CChannelMixer::ProcessData(const BYTE* pData, long cbData, long* pcbDataProcessed) { HRESULT hr = S_OK; long bytesOutput = 0; CAutoLock lock (&m_csOutputSample); while (cbData) { if (m_pNextOutSample) { // If there is not enough space in output sample, flush it long nOffset = m_pNextOutSample->GetActualDataLength(); long nSize = m_pNextOutSample->GetSize(); if (nOffset + m_nOutFrameSize > nSize) { hr = OutputNextSample(); UINT nFrames = nOffset / m_pOutputFormat->Format.nBlockAlign; m_rtInSampleTime += nFrames * UNITS / m_pOutputFormat->Format.nSamplesPerSec; if (FAILED(hr)) { Log("CChannelMixer::ProcessData OutputNextSample failed with: 0x%08x", hr); return hr; } } } // try to get an output buffer if none available if (!m_pNextOutSample && FAILED(hr = RequestNextOutBuffer(m_rtInSampleTime))) { if (pcbDataProcessed) *pcbDataProcessed = bytesOutput + cbData; // we can't realy process the data, lie about it! return hr; } long nOffset = m_pNextOutSample->GetActualDataLength(); long nSize = m_pNextOutSample->GetSize(); BYTE* pOutData = NULL; if (FAILED(hr = m_pNextOutSample->GetPointer(&pOutData))) { Log("CChannelMixer: Failed to get output buffer pointer: 0x%08x", hr); return hr; } ASSERT(pOutData); pOutData += nOffset; int framesToConvert = min(cbData / m_nInFrameSize, (nSize - nOffset) / m_nOutFrameSize); m_pRemap->Remap((float*)pData, (float*)pOutData, framesToConvert); pData += framesToConvert * m_nInFrameSize; bytesOutput += framesToConvert * m_nInFrameSize; cbData -= framesToConvert * m_nInFrameSize; nOffset += framesToConvert * m_nOutFrameSize; m_pNextOutSample->SetActualDataLength(nOffset); if (nOffset + m_nOutFrameSize > nSize) { hr = OutputNextSample(); UINT nFrames = nOffset / m_pOutputFormat->Format.nBlockAlign; m_rtInSampleTime += nFrames * UNITS / m_pOutputFormat->Format.nSamplesPerSec; if (FAILED(hr)) { Log("CChannelMixer::ProcessData OutputNextSample failed with: 0x%08x", hr); return hr; } } // all samples should contain an integral number of frames ASSERT(cbData == 0 || cbData >= m_nInFrameSize); } if (pcbDataProcessed) *pcbDataProcessed = bytesOutput; return hr; }
HRESULT CSampleRateConverter::FlushStream() { HRESULT hr = S_OK; CAutoLock lock (&m_csOutputSample); if (m_pNextOutSample) { if (FAILED(OutputNextSample())) { Log("CSampleRateConverter::FlushStream OutputNextSample failed with: 0x%08x", hr); return hr; } } LONGLONG framesLeft = (m_llFramesInput * m_dSampleRateRation) - m_llFramesOutput; if (framesLeft > 0) { // SRC allows only one call to "flush" so we use a new sample for the last bits of the stream if (!m_pNextOutSample && FAILED(hr = RequestNextOutBuffer(m_rtInSampleTime))) return hr; long nSize = m_pNextOutSample->GetSize(); BYTE *pOutData = NULL; if (FAILED(hr = m_pNextOutSample->GetPointer(&pOutData))) { Log("CSampleRateConverter: Failed to get output buffer pointer: 0x%08x", hr); return hr; } if (nSize / m_nFrameSize < framesLeft) Log("CSampleRateConverter: Overflow - Failed to flush SRC data, increase internal sample size!"); BYTE* tmp[1]; SRC_DATA data; data.data_in = (float*)tmp; data.data_out = (float*)pOutData; data.input_frames = 0; data.output_frames = min(nSize / m_nFrameSize, framesLeft); data.src_ratio = m_dSampleRateRation; data.end_of_input = 1; int srcRet = src_process(m_pSrcState, &data); if (srcRet == 0 && data.output_frames_gen > 0) { ASSERT(data.output_frames_gen == data.output_frames); m_pNextOutSample->SetActualDataLength(data.output_frames_gen * m_nFrameSize); UINT nFrames = m_pNextOutSample->GetActualDataLength() / m_pOutputFormat->Format.nBlockAlign; m_rtInSampleTime += nFrames * UNITS / m_pOutputFormat->Format.nSamplesPerSec; hr = OutputNextSample(); if (FAILED(hr)) { Log("CSampleRateConverter::FlushStream OutputNextSample failed with: 0x%08x", hr); return hr; } } else m_pNextOutSample.Release(); } m_llFramesInput = 0; m_llFramesOutput = 0; int srcRet = src_reset(m_pSrcState); if (srcRet != 0) return S_FALSE; return hr; }
HRESULT CSampleRateConverter::ProcessData(const BYTE* pData, long cbData, long* pcbDataProcessed) { HRESULT hr = S_OK; long bytesProcessed = 0; CAutoLock lock (&m_csOutputSample); while (cbData) { if (m_pNextOutSample) { // If there is not enough space in output sample, flush it long nOffset = m_pNextOutSample->GetActualDataLength(); long nSize = m_pNextOutSample->GetSize(); if (nOffset + m_nFrameSize > nSize) { hr = OutputNextSample(); UINT nFrames = nOffset / m_pOutputFormat->Format.nBlockAlign; m_rtInSampleTime += nFrames * UNITS / m_pOutputFormat->Format.nSamplesPerSec; if (FAILED(hr)) { Log("CSampleRateConverter::ProcessData OutputNextSample failed with: 0x%08x", hr); return hr; } } } // try to get an output buffer if none available if (!m_pNextOutSample && FAILED(hr = RequestNextOutBuffer(m_rtInSampleTime))) { if (pcbDataProcessed) *pcbDataProcessed = bytesProcessed + cbData; // we can't realy process the data, lie about it! return hr; } long nOffset = m_pNextOutSample->GetActualDataLength(); long nSize = m_pNextOutSample->GetSize(); BYTE* pOutData = NULL; if (FAILED(hr = m_pNextOutSample->GetPointer(&pOutData))) { Log("CSampleRateConverter: Failed to get output buffer pointer: 0x%08x", hr); return hr; } ASSERT(pOutData); pOutData += nOffset; SRC_DATA data; data.data_in = (float*)pData; data.data_out = (float*)pOutData; data.input_frames = cbData / m_nFrameSize; data.output_frames = (nSize - nOffset) / m_nFrameSize; data.src_ratio = m_dSampleRateRation; data.end_of_input = 0; int ret = src_process(m_pSrcState, &data); //LogProcessingInfo(&data); bytesProcessed += data.input_frames_used * m_nFrameSize; pData += data.input_frames_used * m_nFrameSize; cbData -= data.input_frames_used * m_nFrameSize; nOffset += data.output_frames_gen * m_nFrameSize; m_llFramesInput += data.input_frames_used; m_llFramesOutput += data.output_frames_gen; m_pNextOutSample->SetActualDataLength(nOffset); if (nOffset + m_nFrameSize > nSize) { hr = OutputNextSample(); UINT nFrames = nOffset / m_pOutputFormat->Format.nBlockAlign; m_rtInSampleTime += nFrames * UNITS / m_pOutputFormat->Format.nSamplesPerSec; if (FAILED(hr)) { Log("CSampleRateConverter::ProcessData OutputNextSample failed with: 0x%08x", hr); return hr; } } // all samples should contain an integral number of frames ASSERT(cbData == 0 || cbData >= m_nFrameSize); } if (pcbDataProcessed) *pcbDataProcessed = bytesProcessed; return hr; }