Replace Audio using IltmmMultiStreamSource and IltmmMultiStreamTarget Example for C

int ReplaceAudio()
{
   IltmmConvert* pVideoConvert;
   IltmmConvert* pAudioConvert;
   IltmmConvert* pDestConvert;
   HRESULT hr;
   IltmmSampleTarget* pVideoTarget = NULL;
   IltmmSampleTarget* pAudioTarget = NULL;
   IltmmMultiStreamSource *pVideoAndAudioSource = NULL;

   BSTR bstr;
   long lState;

   pVideoConvert = NULL;
   pAudioConvert = NULL;
   pDestConvert = NULL;

   CoInitialize(NULL);

   hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pVideoConvert);
   if(FAILED(hr))
   {
      MessageBox(0, "Can't instantiate convert library", "Error", 0);
      return -1;
   }

   hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pAudioConvert);
   if(FAILED(hr))
   {
      MessageBox(0, "Can't instantiate convert library", "Error", 0);
      return -1;
   }

   hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pDestConvert);
   if(FAILED(hr))
   {
      MessageBox(0, "Can't instantiate convert library", "Error", 0);
      return -1;
   }

   hr = CoCreateInstance(&CLSID_ltmmMultiStreamSource, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMultiStreamSource, (void**) &pVideoAndAudioSource);
   if(FAILED(hr))
   {
      MessageBox(0, "Can't instantiate convert library", "Error", 0);
      return -1;
   }

   IltmmMultiStreamSource__put_StreamCount(pVideoAndAudioSource, 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, "c:\\Video.avi", (char*)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, "C:\\Voice.wav", (char*)ltmmMEDIATYPE_Audio, &pAudioTarget, pVideoAndAudioSource, 1);

   // prepare the destination file
   IltmmConvert__put_SourceObject(pDestConvert, pVideoAndAudioSource);
   IltmmConvert__put_TargetFormat(pDestConvert, ltmmConvert_TargetFormat_Avi);

   bstr = T2OLE("C:\\Video_And_Voice.avi");
   IltmmConvert__put_TargetFile(pDestConvert, bstr);

   SysFreeString(bstr);
   IltmmConvert_StartConvert(pDestConvert);

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

   // wait for the destination control to stop the conversion
   IltmmConvert__get_State(pDestConvert, &lState);
   if( lState == ltmmConvert_State_Running )
   {
      IltmmConvert_StopConvert(pDestConvert);
   }

   IltmmConvert_ResetSource(pDestConvert);

   if (pVideoConvert)
   {
      IltmmConvert_Release(pVideoConvert);
      pVideoConvert = NULL;
   }

   if (pAudioConvert)
   {
      IltmmConvert_Release(pAudioConvert);
      pAudioConvert = NULL;
   }

   if (pDestConvert)
   {
      IltmmConvert_Release(pDestConvert);
      pDestConvert = NULL;
   }

   if (pVideoAndAudioSource)
   {
      IltmmMultiStreamSource_Release(pVideoAndAudioSource);
      pVideoAndAudioSource = NULL;
   }

   CoUninitialize();

   return 0;
}

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

   bstrSourceFile = T2OLE(pszSourceFile);
   IltmmConvert__put_SourceFile(pSourceConvert, bstrSourceFile);
   SysFreeString(bstrSourceFile);

   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
   bstrType = T2OLE(mtType);
   IltmmMediaTypeDisp__put_Type(pmt, bstrType);
   SysFreeString(bstrType);

   // make the SampleTarget object accept connections of this media type
   hr = IltmmSampleTarget_SetAcceptedMediaType(*ppSampleTarget, pmt);

   IltmmMediaTypeDisp_Release(pmt);
   pmt = NULL;

   // set the output target object to be sample target
   IltmmConvert__put_TargetObject(pSourceConvert, *ppSampleTarget);

   // start the conversion, so I know the exact media type
   IltmmConvert_StartConvert(pSourceConvert);

   // set the media type for the source stream to be the same as the media type in the input file (video or audio)
   IltmmSampleTarget__getConnectedMediaType(*ppSampleTarget, &pmt);
   IltmmMultiStreamSource_SetMediaType(pVideoAndAudioSource, lStream, pmt);

   // check set sucess:
   IltmmMultiStreamSource__getMediaType(pVideoAndAudioSource, lStream, &pInsertedMeidaType);
   if (pInsertedMeidaType)
      IltmmMediaTypeDisp_Release(pInsertedMeidaType);
}

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;
   VARIANT  vBuffer;
   long     lActualDataLength;
   VARIANT_BOOL vBool;

   do
   {
      hr = IltmmSampleTarget__getSample(pSampleTarget, 3000, &pmsSrc);
      if (!pmsSrc)
         break;

      // get a source sample
      hr = IltmmMultiStreamSource__getSampleBuffer(pVideoAndAudioSource, lStream, 2000, &pmsDst);

      // copy the data to the source sample

      hr = IltmmMediaSampleDisp__get_Buffer(pmsSrc, &vBuffer);
      hr = IltmmMediaSampleDisp__get_ActualDataLength(pmsSrc, &lActualDataLength);
      hr = IltmmMediaSampleDisp_SetData(pmsDst, lActualDataLength, vBuffer);

      // copy the sample time
      IltmmMediaSampleDisp__getTime(pmsSrc, &lStartTimeHi, &lStartTimeLo, &lStopTimeHi, &lStopTimeLo);
      IltmmMediaSampleDisp_SetTime(pmsDst, lStartTimeHi, lStartTimeLo, lStopTimeHi, lStopTimeLo);

      // copy the other flags
      IltmmMediaSampleDisp__get_Discontinuity(pmsSrc, &vBool);
      IltmmMediaSampleDisp__put_Discontinuity(pmsDst, vBool);

      IltmmMediaSampleDisp__get_Preroll(pmsSrc, &vBool);
      IltmmMediaSampleDisp__put_Preroll(pmsDst, vBool);

      IltmmMediaSampleDisp__get_SyncPoint(pmsSrc, &vBool);
      IltmmMediaSampleDisp__put_SyncPoint(pmsDst, vBool);

      //release the source sample
      IltmmMediaSampleDisp_Release(pmsSrc);
      pmsSrc = NULL;

      // deliver the source sample
      IltmmMultiStreamSource_DeliverSample(pVideoAndAudioSource, lStream, 2000, pmsDst);

      // release the source sample
      IltmmMediaSampleDisp_Release(pmsDst);
      pmsDst = NULL;
   }
   while (1);

   // stop the conversion in the source control
   IltmmConvert_StopConvert(pSourceCtrl);

   // deliver end of stream for the current source stream
   hr = IltmmMultiStreamSource_DeliverEndOfStream(pVideoAndAudioSource, lStream, 5000);
}