2009-05-13 15 views
4

DirectShowフィルタグラフに任意のオーディオファイルを渡し、最後に.NET 3.5 C#およびDirectShowを使用して(PCMオーディオ)ストリームオブジェクトを受け取ることをお勧めします。 。ネット。DirectShow.NETを使用してオーディオストリームにアクセスする方法C#

Stream OpenFile(string filename) {...} 

stream.Read(...) 

私は数日間のDirectShow上に読んで、私は考えを把握し始めていると考えられている:私はちょうど言うことができる点に到達したいと思いますフィルタとフィルタグラフ。オーディオを再生する方法やファイルに書き込む方法の例(to file/to device)が見つかりましたが、Streamオブジェクトの解決策が見つからないようです。これも可能ですか?私が何かを見逃してしまった場合に備えて、正しい方向に私を向けることができますか?

ベスト、

Hauke

+0

どのようなファイルの種類(mp3、WAV、WMA ) 欲しいですか? –

+0

これは、DirectShowで実行できるものをすべて取り込むだけです。 mp3、mp2、wma。 DirectShowはそれらのすべてを行うことができます。ストリームをタップするインターフェイスが見つからないだけです。 – Hauke

答えて

5

(私の焦点は、エキゾチックなBWFファイル形式にあったその名。。):

using System; 
    using System.Collections.Generic; 
    using System.Text; 
    using DirectShowLib; 
    using System.Runtime.InteropServices; 
    using System.IO; 

    namespace ConvertBWF2WAV 
    { 
     public class BWF2WavConverter : ISampleGrabberCB 
     { 
      IFilterGraph2 gb = null; 
      ICaptureGraphBuilder2 icgb = null; 
      IBaseFilter ibfSrcFile = null; 
      DsROTEntry m_rot = null; 
      IMediaControl m_mediaCtrl = null; 
      ISampleGrabber sg = null; 


      public BWF2WavConverter() 
      { 
       // Initialize 
       int hr; 
       icgb = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); 
       gb = (IFilterGraph2) new FilterGraph(); 
       sg = (ISampleGrabber)new SampleGrabber(); 

    #if DEBUG 
       m_rot = new DsROTEntry(gb); 
    #endif 
       hr = icgb.SetFiltergraph(gb); 
       DsError.ThrowExceptionForHR(hr); 
      } 

      public void reset() 
      { 
       gb = null; 
       icgb = null; 
       ibfSrcFile = null; 
       m_rot = null; 
       m_mediaCtrl = null; 
      } 

      public void convert(object obj) 
      { 
       string[] pair = obj as string[]; 
       string srcfile = pair[0]; 
       string targetfile = pair[1]; 

       int hr; 

       ibfSrcFile = (IBaseFilter)new AsyncReader(); 
       hr = gb.AddFilter(ibfSrcFile, "Reader"); 
       DsError.ThrowExceptionForHR(hr); 

       IFileSourceFilter ifileSource = (IFileSourceFilter)ibfSrcFile; 
       hr = ifileSource.Load(srcfile, null); 
       DsError.ThrowExceptionForHR(hr); 

       // the guid is the one from ffdshow 
       Type fftype = Type.GetTypeFromCLSID(new Guid("0F40E1E5-4F79-4988-B1A9-CC98794E6B55")); 
       object ffdshow = Activator.CreateInstance(fftype); 
       hr = gb.AddFilter((IBaseFilter)ffdshow, "ffdshow"); 
       DsError.ThrowExceptionForHR(hr); 

       // the guid is the one from the WAV Dest sample in the SDK 
       Type type = Type.GetTypeFromCLSID(new Guid("3C78B8E2-6C4D-11d1-ADE2-0000F8754B99")); 
       object wavedest = Activator.CreateInstance(type); 
       hr = gb.AddFilter((IBaseFilter)wavedest, "WAV Dest"); 
       DsError.ThrowExceptionForHR(hr); 

       // manually tell the graph builder to try to hook up the pin that is left 
       IPin pWaveDestOut = null; 
       hr = icgb.FindPin(wavedest, PinDirection.Output, null, null, true, 0, out pWaveDestOut); 
       DsError.ThrowExceptionForHR(hr); 

       // render step 1 
       hr = icgb.RenderStream(null, null, ibfSrcFile, (IBaseFilter)ffdshow, (IBaseFilter)wavedest); 
       DsError.ThrowExceptionForHR(hr); 

       // Configure the sample grabber 
       IBaseFilter baseGrabFlt = sg as IBaseFilter; 
       ConfigSampleGrabber(sg); 
       IPin pGrabberIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); 
       IPin pGrabberOut = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Output, 0); 
       hr = gb.AddFilter((IBaseFilter)sg, "SampleGrabber"); 
       DsError.ThrowExceptionForHR(hr); 
       AMMediaType mediatype = new AMMediaType(); 
       sg.GetConnectedMediaType(mediatype); 

       hr = gb.Connect(pWaveDestOut, pGrabberIn); 
       DsError.ThrowExceptionForHR(hr); 

       // file writer 
       FileWriter file_writer = new FileWriter(); 
       IFileSinkFilter fs = (IFileSinkFilter)file_writer; 
       fs.SetFileName(targetfile, null); 
       hr = gb.AddFilter((DirectShowLib.IBaseFilter)file_writer, "File Writer"); 
       DsError.ThrowExceptionForHR(hr); 

       // render step 2 
       AMMediaType mediatype2 = new AMMediaType(); 
       pWaveDestOut.ConnectionMediaType(mediatype2); 
       gb.Render(pGrabberOut); 

       // alternatively to the file writer use the NullRenderer() to just discard the rest 

       // assign control 
       m_mediaCtrl = gb as IMediaControl; 

       // run 
       hr = m_mediaCtrl.Run(); 
       DsError.ThrowExceptionForHR(hr); 


      } 


      // 
      // configure the SampleGrabber filter of the graph 
      // 
      void ConfigSampleGrabber(ISampleGrabber sampGrabber) 
      { 
       AMMediaType media; 

       // set the media type. works with "stream" somehow... 
       media = new AMMediaType(); 
       media.majorType = MediaType.Stream; 
       //media.subType = MediaSubType.WAVE; 
       //media.formatType = FormatType.WaveEx; 

       // that's the call to the ISampleGrabber interface 
       sg.SetMediaType(media); 

       DsUtils.FreeAMMediaType(media); 
       media = null; 

       // set BufferCB as the desired Callback function 
       sg.SetCallback(this, 1); 
      } 

      public int SampleCB(double a, IMediaSample b) 
      { 
       return 0; 
      } 

      /// <summary> 
      /// Called on each SampleGrabber hit. 
      /// </summary> 
      /// <param name="SampleTime">Starting time of the sample, in seconds.</param> 
      /// <param name="pBuffer">Pointer to a buffer that contains the sample data.</param> 
      /// <param name="BufferLen">Length of the buffer pointed to by pBuffer, in bytes.</param> 
      /// <returns></returns> 
      public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen) 
      { 
       byte[] buffer = new byte[BufferLen]; 
       Marshal.Copy(pBuffer, buffer, 0, BufferLen); 
       using (BinaryWriter binWriter = new BinaryWriter(File.Open(@"C:\directshowoutput.pcm", FileMode.Append))) 
       { 
        binWriter.Write(buffer); 
       } 
       return 0; 
      } 
     } 
    } 
+1

共有していただきありがとうございます。 –

1

このソリューションにあなたを導くこと(AVILibrary Wrapper)、それは(私は気持ちが再生ハードウェアを使用してコードをインタフェースに非常にバイアスされ得るもの)ベースのDirectSoundていないが、答えかもしれない。

もう1つのアプローチは、hereです。

1

NAudioはどうですか? http://www.codeplex.com/naudio ストリーム実装があります。私はあなたと私自身の問題に私の解決策を共有したいと思います

+0

ファイルタイプにNAudioがあまりにも厳しいと感じました。 – Hauke

+0

NAudioは現在、インストールされているACMコーデックとDirectX Media Objects(DMO)にアクセスできます。 DirectShowフィルターは、今後追加したいものです。 –

関連する問題