Replace Audio using IltmmMultiStreamSource and IltmmMultiStreamTarget Example for C++

void PrepareSampleAndTarget(IltmmConvert* pSourceConvert, WCHAR pwszSourceFile[256], WCHAR mtType[40], IltmmSampleTarget** ppSampleTarget, IltmmMultiStreamSource* pVideoAndAudioSource, long lStream)
{
   IltmmMediaTypeDisp *pInsertedMeidaType;
   IltmmMediaTypeDisp *pmt;
   USES_CONVERSION;
   pSourceConvert->put_SourceFile(pwszSourceFile);

   HRESULT hr = CoCreateInstance(CLSID_ltmmSampleTarget, NULL, CLSCTX_INPROC_SERVER, IID_IltmmSampleTarget, (void**) ppSampleTarget);
   if(FAILED(hr))
   {
      return;
   }
   hr = CoCreateInstance(CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMediaTypeDisp, (void**) &pmt);
   if(FAILED(hr))
   {
      return;
   }
   // create a ltmmMediaType and indicate the accepted type
   pmt->put_Type(mtType);

   // make the SampleTarget object accept connections of this media type
   hr = (*ppSampleTarget)->SetAcceptedMediaType(pmt);
   pmt->Release();
   pmt = NULL;
   // set the output target object to be sample target
   pSourceConvert->put_TargetObject(*ppSampleTarget);
   // start the conversion, so I know the exact media type
   pSourceConvert->StartConvert();
   // set the media type for the source stream to be the same as the media type in the input file (video or audio)
   (*ppSampleTarget)->GetConnectedMediaType(&pmt);
   pVideoAndAudioSource->SetMediaType(lStream, pmt);
   pVideoAndAudioSource->GetMediaType(0, &pInsertedMeidaType);
   if (pInsertedMeidaType)
      pInsertedMeidaType->Release();
}

void CopySamples(IltmmConvert* pSourceCtrl, IltmmSampleTarget* pSampleTarget,
                 IltmmMultiStreamSource *pVideoAndAudioSource, long lStream)
{
   IltmmMediaSampleDisp*  pmsSrc = NULL;
   IltmmMediaSampleDisp*  pmsDst = NULL;
   long              lStartTimeHi;
   long              lStartTimeLo;
   long              lStopTimeHi;
   long              lStopTimeLo;
   HRESULT hr;
   do
   {
      hr = pSampleTarget->GetSample(3000, &pmsSrc);
      if (!pmsSrc)
         break;
      // get a source sample
      hr = pVideoAndAudioSource->GetSampleBuffer(lStream, 2000, &pmsDst);
      if (hr == E_FAIL)
         hr = pVideoAndAudioSource->GetSampleBuffer(lStream, 3000, &pmsDst);
      // copy the data to the source sample
      VARIANT  vBuffer;
      long     lActualDataLength;
      hr = pmsSrc->get_Buffer(&vBuffer);
      hr = pmsSrc->get_ActualDataLength(&lActualDataLength);
      hr = pmsDst->SetData(lActualDataLength, vBuffer);
      // copy the sample time
      pmsSrc->GetTime(&lStartTimeHi, &lStartTimeLo, &lStopTimeHi, &lStopTimeLo);
      pmsDst->SetTime(lStartTimeHi, lStartTimeLo, lStopTimeHi, lStopTimeLo);
      // copy the other flags
      VARIANT_BOOL vBool;
      pmsSrc->get_Discontinuity(&vBool);
      pmsDst->put_Discontinuity(vBool);
      pmsSrc->get_Preroll(&vBool);
      pmsDst->put_Preroll(vBool);
      pmsSrc->get_SyncPoint(&vBool);
      pmsDst->put_SyncPoint(vBool);
      //release the source sample
      pmsSrc->Release();
      pmsSrc = NULL;
      // deliver the source sample
      pVideoAndAudioSource->DeliverSample(lStream, 2000, pmsDst);
      // release the source sample
      pmsDst->Release();
      pmsDst = NULL;
   }   while (1);
   // stop the conversion in the source control
   pSourceCtrl->StopConvert();
   // deliver end of stream for the current source stream
   //
   hr = pVideoAndAudioSource->DeliverEndOfStream(lStream, 5000);
}

void Convert(CString strVid, CString strAud, CString strDest)
{
   IltmmConvert* pVideoConvert;
   IltmmConvert* pAudioConvert;
   IltmmConvert* pDestConvert;
   pVideoConvert = NULL;
   pAudioConvert = NULL;
   pDestConvert = NULL;
   CoInitialize(NULL);
   HRESULT hr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &pVideoConvert);
   if(FAILED(hr))
   {
      AfxMessageBox(_T("Can't instantiate convert library"));
   }
   hr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &pAudioConvert);
   if(FAILED(hr))
   {
      AfxMessageBox(_T("Can't instantiate convert library"));
   }
   hr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &pDestConvert);
   if(FAILED(hr))
   {
      AfxMessageBox(_T("Can't instantiate convert library"));
   }
   IltmmSampleTarget* pVideoTarget = NULL;
   IltmmSampleTarget* pAudioTarget = NULL;
   IltmmMultiStreamSource *pVideoAndAudioSource = NULL;
   hr = CoCreateInstance(CLSID_ltmmMultiStreamSource, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMultiStreamSource, (void**) &pVideoAndAudioSource);
   if(FAILED(hr))
   {
      AfxMessageBox(_T("Can't instantiate convert library"));
   }
   pVideoAndAudioSource->put_StreamCount(2);

   /*
   Prepare pVideoConvert and set its source file to VideoFile.
   Convert only the video stream
   Create a new pVideoTarget object and set as the sample target object in pVideoConvert
   Set the stream media type for pin 0 of VideoAndAudioSource to be the same as the video media type
   Also starts the conversion in pVideoConvert
   */
   PrepareSampleAndTarget(pVideoConvert, strVid.GetBuffer(), ltmmMEDIATYPE_Video, &pVideoTarget, pVideoAndAudioSource, 0);

   /*
   Prepare AudioCtrl and set its source file to AudioFile.
   Convert only the audio stream
   Create a new AudioTarget object and set as the sample target object in AudioCtrl
   Set the stream media type for pin 1 of VideoAndAudioSource to be the same as the audio media type
   Also starts the conversion in AudioCtrl
   */
   PrepareSampleAndTarget(pAudioConvert, strAud.GetBuffer(), ltmmMEDIATYPE_Audio, &pAudioTarget, pVideoAndAudioSource, 1);

   // prepare the destination file
   pDestConvert->put_SourceObject(pVideoAndAudioSource);
   pDestConvert->put_TargetFormat(ltmmConvert_TargetFormat_Avi);
   BSTR bstr = strDest.AllocSysString();
   pDestConvert->put_TargetFile(bstr);
   SysFreeString(bstr);
   pDestConvert->StartConvert();

   // Copy all the video samples from the Video file to the destination file
   CopySamples(pVideoConvert, pVideoTarget, pVideoAndAudioSource, 0);

   // Copy all the audio samples from the Audio file to the destination file
   CopySamples(pAudioConvert, pAudioTarget, pVideoAndAudioSource, 1);
   hr = pVideoAndAudioSource->DeliverEndOfStream(0, 5000);
   hr = pVideoAndAudioSource->DeliverEndOfStream(1, 5000);

   // wait for the destination control to stop the conversion
   long lState;
   pDestConvert->get_State(&lState);
   while (lState == ltmmConvert_State_Running)
   {
      Sleep(5000);
      pDestConvert->get_State(&lState);
      pDestConvert->StopConvert();
   }
   pDestConvert->ResetSource();

   if (pVideoConvert)
   {
      pVideoConvert->Release();
      pVideoConvert = NULL;
   }

   if (pAudioConvert)
   {
      pAudioConvert->Release();
      pAudioConvert = NULL;
   }
   if (pDestConvert)
   {
      pDestConvert->Release();
      pDestConvert = NULL;
   }
   if (pVideoAndAudioSource)
   {
      pVideoAndAudioSource->Release();
      pVideoAndAudioSource = NULL;
   }
   CoUninitialize();
}