4


4

私がやりたいことは、DirectShowフィルタグラフに任意のオーディオファイルを渡し、最後に.NET 3.5 C#とDirectShow.NETを使って(PCMオーディオ)ストリームオブジェクトを受け取ることです。 私がちょうど言うことができるという点に到達したいです。

ストリームOpenFile(文字列ファイル名){...}

そして

stream.Read(...)

私は2、3日間DirectShowを読んできましたが、私はフィルターとフィルターグラフのアイデアをつかみ始めたと思います。 例が見つかりました( ファイル / http://replay.waybackmachine.org/20091021154718/http: //geocities.com/contactgirish/DirectShow.html [to device])オーディオを再生したりファイルに書き込んだりする方法はありますが、Streamオブジェクトの解決策を見つけることはできません。 これでも可能ですか? 私が何かを逃した場合にあなたは私を正しい方向に向けることができますか?

ベスト、

ホーク

3 Answer


5


私はあなたと私自身の問題に対する私の解決策を共有したいと思います(私の焦点はエキゾチックなbwfファイルフォーマットにありました。 それ故に名前。):

システムを使用する。 System.Collections.Genericを使用します。 System.Textを使用します。 DirectShowLibを使用する。 System.Runtime.InteropServicesを使用します。 System.IOを使用します。

名前空間ConvertBWF2WAV {パブリッククラスBWF2WavConverter:ISampleGrabberCB {IFilterGraph2 gb = null;} ICaptureGraphBuilder2 icgb = null; IBaseFilter ibfSrcFile = null; DsROTEntry m_rot = null。 IMediaControl m_mediaCtrl = null。 ISampleGrabber sg = null;

public BWF2WavConverter(){// 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 [];文字列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);

// guidはffdshow Type fftype = Type.GetTypeFromCLSID(new Guid( "0F40E1E5-4F79-4988-B1A9-CC98794E6B55"))からのものです。オブジェクトffdshow = Activator.CreateInstance(fftype); hr = gb.AddFilter((IBaseFilter)ffdshow、 "ffdshow"); DsError.ThrowExceptionForHR(hr);

// guidは、SDKのWAV DestサンプルのものですType = Type.GetTypeFromCLSID(new Guid( "3C78B8E2-6C4D-11d1-ADE2-0000F8754B99"));オブジェクトwavedest = Activator.CreateInstance(type); hr = gb.AddFilter((IBaseFilter)wavedest、 "WAV Dest"); DsError.ThrowExceptionForHR(hr);

//手動でグラフビルダーに、残っているピンを引っ掛けようとするよう指示するIPin pWaveDestOut = null; hr = icgb.FindPin(wavedest、PinDirection.Output、null、null、true、0、out pWaveDestOut); DsError.ThrowExceptionForHR(hr);

//ステップ1をレンダリングするhr = icgb.RenderStream(null、null、ibfSrcFile、(IBaseFilter)ffdshow、(IBaseFilter)wavedest); DsError.ThrowExceptionForHR(hr);

//サンプルグラバーIBaseFilter baseGrabFlt = sgを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(メディアタイプ);

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

//ファイルライター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);

//ステップ2をレンダリングします。AMMediaType mediatype2 = new AMMediaType(); pWaveDestOut.ConnectionMediaType(メディアタイプ2); gb.Render(pGrabberOut);

//ファイルライターの代わりにNullRenderer()を使用して残りの部分を破棄する

// IMediaControlとしてコントロールm_mediaCtrl = gbを割り当てます。

// hr = m_mediaCtrl.Run();を実行します。 DsError.ThrowExceptionForHR(hr);

}

// //グラフのSampleGrabberフィルタを構成する// void ConfigSampleGrabber(ISampleGrabber sampGrabber){AMMediaType media;

//メディアタイプを設定します。 どういうわけか "ストリーム"で動作します... media = new AMMediaType(); media.majorType = MediaType.Stream; //media.subType = MediaSubType.WAVE; //media.formatType = FormatType.WaveEx;

//これはISampleGrabberインターフェイスの呼び出しです。sg.SetMediaType(media);

DsUtils.FreeAMMediaType(メディア)。 media = null。

// BufferCBを目的のコールバック関数として設定します。sg.SetCallback(this、1); }

public int SampleCB(double a、IMediaSample b){戻り値0; }

/// /// SampleGrabberがヒットするたびに呼び出されます。 /// ///サンプルの開始時間(秒)。 ///サンプルデータを含むバッファへのポインタ。 /// pBufferが指すバッファーの長さ(バイト単位) /// 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); 0を返します。 }}}


1


これ( AVILibrary Wrapper)はあなたを解決策に導いてくれるかもしれません、それはDirectSoundベースではありません(それは私があなたのインターフェースに非常に偏っていると感じます再生ハードウェアを使用してコード化してください)

別のアプローチは hereにあります。