2012-05-10 25 views
0

私のC#アプリケーションのNAudioよりもはるかに単純なバージョンのオープンソースコードが見つかりました。私がしたいのは、スピーカーから簡単に音を出して、プラグインされているかどうかをテストし、マイクを聞きたいからです。プロジェクト自体は大丈夫でしたが、小さなチャックに少しリファクタリングできると感じました。私が見つけたもう一つの事は、WaveOutBuffer.csファイルとWaveInBuffer.csファイルが非常に似ているということです。だから私は抽象クラスWaveBufferを作り始めました。これには、渡されるすべての同様の関数と変数が含まれています。私が悩んでいるのは以下の通りです。別のWaveNative.csファイルにデリゲートがあります。私は非常に重要である可能性があることを知っているので、代表者とイベントにはとても新しいです。しかし、私はそれが使用されるようにセットアップされている方法が好きではありません。だから、私は各ファイルにあるものとそれがどのように使用されているのかを投稿し、次に私が働くことを試みてきたものを示します。多分私たちの心の間で、これを統合してより効率的にするためにリファクタリングすることができます:)関数のデリゲート関数を統合しても意味がありません

です。

WaveNative.cs

//callbacks 
public delegate void WaveDelegate(IntPtr hdrvr, int uMsg, int dwUser, ref WaveHdr wavhdr, int dwParam2); 

WaveInBuffer.cs/WaveOutBuffer.cs

internal static void WaveInProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2) 
    { 
     if (uMsg == WaveNative.MM_WIM_DATA) 
     { 
      try 
      { 
       GCHandle h = (GCHandle)wavhdr.dwUser; 
       WaveInBuffer buf = (WaveInBuffer)h.Target; 
       buf.OnCompleted(); 
      } 
      catch 
      { 
      } 
     } 
    } 
//WaveOutBuffer.cs version 
    internal static void WaveOutProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2) 
    { 
     if (uMsg == WaveNative.MM_WOM_DONE) 
     { 
      try 
      { 
       GCHandle h = (GCHandle)wavhdr.dwUser; 
       WaveOutBuffer buf = (WaveOutBuffer)h.Target; 
       buf.OnCompleted(); 
      } 
      catch 
      { 
      } 
     } 
    } 

WaveInRecorder.cs/WaveOutRecorder

private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveInBuffer.WaveInProc); 
private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveOutBuffer.WaveOutProc); 
私は、このようなHeaderDataとしてWaveBufferの抽象バージョンでは他のほとんどのものを統合しました

[DllImport(mmdll)] 
    public static extern int waveOutOpen(out IntPtr hWaveOut, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags); 
    [DllImport(mmdll)] 
    public static extern int waveInOpen(out IntPtr phwi, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags); 

次のよう最後に

彼らはのPInvoke呼び出しのために使用されている、ヘッダのサイズ、のIntPtrデータ、 GCHandle HeaderHandle、およびHeaderDataHandleがあります。 OnCompleteCommand、bool Busy、およびAutoResetEventのWaitForコマンド。それが何のために使われているのかは分かっていませんが、それは使われていますが、各ファイルで同じように使われています。あなたの忍耐とこのスレッドを通じて読んでいただきありがとうございます。

EDIT

混乱のため申し訳ありませんが、私はので、私は私が尋ねることを意味したものを尋ねるのを忘れて、すべてこのようなものを見つけるのに包まれました。基本的には、ほぼ同じことをするこれらの2つの機能をどのように組み合わせることができますか?このDelegateは、WaveInBuffer/WaveOutBufferで新しいインスタンスを作成できるように、WaveNativeからどのように機能しますか?同じことを意味します。私はちょうど、いつも他のクラスから呼び出すか、基本クラスを呼び出す必要があると仮定しました。 m_BufferedProcに関しては、私が理解することが難しいので、コード全体を投稿します。私が投稿しているこのコードは、自分のものではないことに気をつけてください。ここには

public class WaveInRecorder : IDisposable 
{ 
    private IntPtr m_WaveIn; 
    private WaveInBuffer m_Buffers; // linked list 
    private WaveInBuffer m_CurrentBuffer; 
    private Thread m_Thread; 
    private BufferDoneEventHandler m_DoneProc; 
    private bool m_Finished; 

    private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveInBuffer.WaveInProc); 

    public static int DeviceCount 
    { 
     get { return WaveNative.waveInGetNumDevs(); } 
    } 

    public WaveInRecorder(int device, WaveFormat format, int bufferSize, int bufferCount, BufferDoneEventHandler doneProc) 
    { 
     m_DoneProc = doneProc; 
     WaveInHelper.Try(WaveNative.waveInOpen(out m_WaveIn, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION)); 
     AllocateBuffers(bufferSize, bufferCount); 
     for (int i = 0; i < bufferCount; i++) 
     { 
      SelectNextBuffer(); 
      m_CurrentBuffer.Record(); 
     } 
     WaveInHelper.Try(WaveNative.waveInStart(m_WaveIn)); 
     m_Thread = new Thread(new ThreadStart(ThreadProc)); 
     m_Thread.Start(); 
    } 
    ~WaveInRecorder() 
    { 
     Dispose(); 
    } 
    public void Dispose() 
    { 
     if (m_Thread != null) 
      try 
      { 
       m_Finished = true; 
       if (m_WaveIn != IntPtr.Zero) 
        WaveNative.waveInReset(m_WaveIn); 
       WaitForAllBuffers(); 
       m_Thread.Join(); 
       m_DoneProc = null; 
       FreeBuffers(); 
       if (m_WaveIn != IntPtr.Zero) 
        WaveNative.waveInClose(m_WaveIn); 
      } 
      finally 
      { 
       m_Thread = null; 
       m_WaveIn = IntPtr.Zero; 
      } 
     GC.SuppressFinalize(this); 
    } 
    private void ThreadProc() 
    { 
     while (!m_Finished) 
     { 
      Advance(); 
      if (m_DoneProc != null && !m_Finished) 
       m_DoneProc(m_CurrentBuffer.Data, m_CurrentBuffer.Size); 
      m_CurrentBuffer.Record(); 
     } 
    } 
    private void AllocateBuffers(int bufferSize, int bufferCount) 
    { 
     FreeBuffers(); 
     if (bufferCount > 0) 
     { 
      m_Buffers = new WaveInBuffer(m_WaveIn, bufferSize); 
      WaveInBuffer Prev = m_Buffers; 
      try 
      { 
       for (int i = 1; i < bufferCount; i++) 
       { 
        WaveInBuffer Buf = new WaveInBuffer(m_WaveIn, bufferSize); 
        Prev.NextBuffer = Buf; 
        Prev = Buf; 
       } 
      } 
      finally 
      { 
       Prev.NextBuffer = m_Buffers; 
      } 
     } 
    } 
    private void FreeBuffers() 
    { 
     m_CurrentBuffer = null; 
     if (m_Buffers != null) 
     { 
      WaveInBuffer First = m_Buffers; 
      m_Buffers = null; 

      WaveInBuffer Current = First; 
      do 
      { 
       WaveInBuffer Next = Current.NextBuffer; 
       Current.Dispose(); 
       Current = Next; 
      } while(Current != First); 
     } 
    } 
    private void Advance() 
    { 
     SelectNextBuffer(); 
     m_CurrentBuffer.WaitFor(); 
    } 
    private void SelectNextBuffer() 
    { 
     m_CurrentBuffer = m_CurrentBuffer == null ? m_Buffers : m_CurrentBuffer.NextBuffer; 
    } 
    private void WaitForAllBuffers() 
    { 
     WaveInBuffer Buf = m_Buffers; 
     while (Buf.NextBuffer != m_Buffers) 
     { 
      Buf.WaitFor(); 
      Buf = Buf.NextBuffer; 
     } 
    } 

あなたは、そのコードは私のものではなく、むしろIanier Munozのことを覚えておいてください。私は私が働いている同様のバージョンは、あなたが私は(ここでは完全に実装されていない)、それを使用する方法http://code.google.com/p/adli/source/browse/#svn%2Ftrunk%2FAspects%2FCustom%2FAudio

http://code.google.com/p/adli/source/browse/trunk/Aspects/Panels/Main%20Panels/AudioBrightnessPanel.cs

表情ででそれから抽出されたコードを閲覧することができます持っていますマイクテストのアクションリスナー

もう一度ご不便をおかけして申し訳ありませんが、私は再び質問なしで質問を投稿しないようにします。

+0

されています2つの 'm_BufferProc'フィールドが定義され使用されていますか? –

+1

私はその質問が何であるか明確ではない。 –

+1

最初に何もしない 'try' /' catch'ブロックがあります... – MoonKnight

答えて

0

ブロック場合だけでなく、あなたが一緒に2をマージするのはかなり簡単意味し、相互に排他的なんだ...(私はその悪のために空のcatchブロックを削除)

internal static void WaveProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2) 
{ 
    GCHandle h = (GCHandle)wavhdr.dwUser; 
    if (uMsg == WaveNative.MM_WIM_DATA) 
    { 
     WaveInBuffer buf = (WaveInBuffer)h.Target; 
     buf.OnCompleted(); 
    } 
    if (uMsg == WaveNative.MM_WOM_DONE) 
    { 
     WaveOutBuffer buf = (WaveOutBuffer)h.Target; 
     buf.OnCompleted(); 
    } 
} 

private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveInBuffer.WaveProc);

+0

私はあなたがこれを書いた方法が好きですが、これは本当に最善のアプローチですか? (私は無知な意味でこれを意味しています)私は、ある人がデリゲートを持っていて、イベントを持っているときに慣れています。条件が発生したときにnullをチェックし、そのイベントを発生させます。それは私がここですべきことではありませんか?またはこれはより良いアプローチですか? –

関連する問題