Replace Audio using IltmmMultiStreamSource and IltmmMultiStreamTarget Example for C++

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);
   SetWindowText("Prepare the video control...");
   /*  
      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(strVid.GetAllocLength()), (char*)ltmmMEDIATYPE_Video, &pVideoTarget, pVideoAndAudioSource, 0);

   SetWindowText("Prepare the audio control...");
   /*
      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(strAud.GetAllocLength()), (char*)ltmmMEDIATYPE_Audio, &pAudioTarget, pVideoAndAudioSource, 1);

   SetWindowText("Prepare the destination control...");
   // 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();

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

   SetWindowText("Copy the audio samples...");
   // 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();
   SetWindowText("Done.");

   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();
}

void PrepareSampleAndTarget(IltmmConvert* pSourceConvert, char pszSourceFile[256], char mtType[40], IltmmSampleTarget** ppSampleTarget, IltmmMultiStreamSource* pVideoAndAudioSource, long lStream)
{
   IltmmMediaTypeDisp *pInsertedMeidaType;
   IltmmMediaTypeDisp *pmt;

   USES_CONVERSION;

   BSTR bstrSourceFile = A2BSTR(pszSourceFile);
   pSourceConvert->put_SourceFile(bstrSourceFile);
   SysFreeString(bstrSourceFile);

   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
   BSTR bstrType;
   bstrType = A2BSTR(mtType);
   pmt->put_Type(bstrType);
   SysFreeString(bstrType);

   // 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);
}