void CALLBACK CAacConverter::OnLpcmFrame(const BYTE *pData, const DWORD dwSamples, const BYTE byChannel, PVOID pParam) { CAacConverter *pThis = static_cast<CAacConverter *>(pParam); DWORD dwBlockAlign = pThis->m_byOutputChannel * 2; // 出力ポインタ取得 DWORD dwOutSize = 0UL; pThis->m_PcmBuffer.SetSize(dwSamples * dwBlockAlign); BYTE *pOutBuff = pThis->m_PcmBuffer.GetData(); if(pData){ if(pThis->m_byOutputChannel == 6){ // アップミックス? switch(byChannel){ case 1U: dwOutSize = UpMixMono((short *)pOutBuff, (const short *)pData, dwSamples); break; case 2U: dwOutSize = UpMixStreao((short *)pOutBuff, (const short *)pData, dwSamples); break; case 6U: dwOutSize = UpMixSurround((short *)pOutBuff, (const short *)pData, dwSamples); break; } }else if(pThis->m_byOutputChannel == 2){ // ダウンミックス switch(byChannel){ case 1U: dwOutSize = DownMixMono((short *)pOutBuff, (const short *)pData, dwSamples); break; case 2U: dwOutSize = DownMixStreao((short *)pOutBuff, (const short *)pData, dwSamples); break; case 6U: dwOutSize = DownMixSurround((short *)pOutBuff, (const short *)pData, dwSamples); break; } if(m_StereoToMono){ StereoToMono((short *)pOutBuff, dwSamples , m_StereoToMono == 1 ? TRUE : FALSE); } } } else { dwOutSize = dwSamples * dwBlockAlign; ZeroMemory(pOutBuff,dwOutSize); } // 次のデコーダにサンプルを渡す pThis->m_byLastChannelNum = byChannel; if(m_CutFrame){ if(m_CutFrame >= pThis->m_PcmBuffer.GetSize()/dwBlockAlign){ m_CutFrame -= pThis->m_PcmBuffer.GetSize()/dwBlockAlign; pThis->m_PcmBuffer.ClearSize(); return; } else { pThis->m_PcmBuffer.TrimHead(m_CutFrame*dwBlockAlign); m_CutFrame = 0; } } else if(m_HoseiPol < 0){ Mabiki(&pThis->m_PcmBuffer,m_HoseiPol,dwBlockAlign); } else if (m_HoseiPol > 0){ Hokan(&pThis->m_PcmBuffer,m_HoseiPol,dwBlockAlign); } m_total_frame += pThis->m_PcmBuffer.GetSize()/dwBlockAlign; m_pes_frame += pThis->m_PcmBuffer.GetSize()/dwBlockAlign; pThis->OutputMedia(&pThis->m_PcmBuffer); }
HRESULT CAudioDecFilter::ProcessPcm(const BYTE *pData, const DWORD Samples, const CAudioDecoder::AudioInfo &Info, FrameSampleInfo *pSampleInfo) { const bool bSurround = (Info.Channels == 6 && !m_bDownMixSurround); const int OutChannels = bSurround ? 6 : 2; // メディアタイプの更新 bool bMediaTypeChanged = false; WAVEFORMATEX *pwfx = pointer_cast<WAVEFORMATEX*>(m_MediaType.Format()); if (*m_MediaType.FormatType() != FORMAT_WaveFormatEx || (!bSurround && pwfx->wFormatTag != WAVE_FORMAT_PCM) || (bSurround && pwfx->wFormatTag != WAVE_FORMAT_EXTENSIBLE)) { CMediaType &mt = pSampleInfo->MediaType; mt.SetType(&MEDIATYPE_Audio); mt.SetSubtype(&MEDIASUBTYPE_PCM); mt.SetFormatType(&FORMAT_WaveFormatEx); pwfx = pointer_cast<WAVEFORMATEX*>( mt.AllocFormatBuffer(bSurround ? sizeof (WAVEFORMATEXTENSIBLE) : sizeof(WAVEFORMATEX))); if (pwfx == NULL) return E_OUTOFMEMORY; if (!bSurround) { pwfx->wFormatTag = WAVE_FORMAT_PCM; pwfx->nChannels = 2; pwfx->cbSize = 0; } else { WAVEFORMATEXTENSIBLE *pExtensible = pointer_cast<WAVEFORMATEXTENSIBLE*>(pwfx); pExtensible->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; pExtensible->Format.nChannels = 6; pExtensible->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); pExtensible->dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; pExtensible->Samples.wValidBitsPerSample = 16; pExtensible->SubFormat = MEDIASUBTYPE_PCM; } pwfx->nSamplesPerSec = FREQUENCY; pwfx->wBitsPerSample = 16; pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8; pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; mt.SetSampleSize(pwfx->nBlockAlign); pSampleInfo->bMediaTypeChanged = true; pSampleInfo->MediaBufferSize = SAMPLES_PER_FRAME * pwfx->nBlockAlign; } const DWORD BuffSize = Samples * OutChannels * sizeof(short); if (pSampleInfo->pData->SetSize(BuffSize) < BuffSize) return E_OUTOFMEMORY; BYTE *pOutBuff = pSampleInfo->pData->GetData(); if (pData != NULL) { DWORD OutSize; // ダウンミックス switch (Info.Channels) { case 1: OutSize = MonoToStereo(pointer_cast<short *>(pOutBuff), pointer_cast<const short *>(pData), Samples); break; case 2: OutSize = DownMixStereo(pointer_cast<short *>(pOutBuff), pointer_cast<const short *>(pData), Samples); break; case 6: if (bSurround) { OutSize = MapSurroundChannels(pointer_cast<short *>(pOutBuff), pointer_cast<const short *>(pData), Samples); } else { OutSize = DownMixSurround(pointer_cast<short *>(pOutBuff), pointer_cast<const short *>(pData), Samples); } break; } if (m_bGainControl && (Info.Channels < 6 || bSurround)) { GainControl(pointer_cast<short *>(pOutBuff), OutSize / sizeof(short), bSurround ? m_SurroundGain : m_Gain); } } else { ::ZeroMemory(pOutBuff, BuffSize); } if (m_pStreamCallback) { m_pStreamCallback(pointer_cast<short *>(pOutBuff), Samples, OutChannels, m_pStreamCallbackParam); } pSampleInfo->Samples = Samples; return S_OK; }