2011-07-13 54 views
1

我使用NAudio(但適用於直接閱讀)捕獲麥克風波形數據。看來,如果我的應用程序很忙,它會丟棄/跳過麥克風的一些輸入數據。從麥克風無損閱讀

我已經將閱讀線程設置爲最高優先級,但我在同一時間在其他幾個線程中進行繁重的計算。

有沒有辦法讀取數據無損?
(或者它是無損的,我的錯誤在其他地方?)

回答

0

當我製作一個類似的應用程序,並有類似的問題,事實證明,我需要一個緩衝區,可以保存至少3秒的數據。嘗試將緩衝區增加到10秒的數據,如果它不能解決你的問題,那麼還有更多的問題。如果它工作嘗試減少緩衝區的大小,直到它正常工作

編輯:這裏快速&骯髒管理DX記錄,您可以嘗試。

public class BMSRecordingEventArgs : EventArgs 
{ 
    byte[] data; 
    bool endRec; 

    public BMSRecordingEventArgs(byte[] data, bool endRec) 
    { 
     this.data = data; 
     this.endRec = endRec; 
    } 
    public byte[] Data 
    { 
     get { return data; } 
    } 
    public bool EndRec 
    { 
     get { return endRec; } 
    } 
} 
public class AudioRecorder 
{ 
    public delegate void DataReceivedHandler(object sender, BMSRecordingEventArgs e); 
    public event DataReceivedHandler DataReceivedHandle; 

    public const int CAPTURE_BUFFER_SIZE = 32000; 
    DXS.Capture dxsCapDev; 
    DXS.CaptureBuffer dxsCapBuffer; 
    DXS.CaptureBufferDescription dxsCapBufferDesc; 
    System.Threading.Thread thrdCapturingThread; 
    DXS.BufferPositionNotify[] dxsBpna; 
    private volatile bool StopRec; 

    System.Threading.ManualResetEvent mreStillRunning = new System.Threading.ManualResetEvent(false); 
    DXS.BufferPositionNotify dxsBPNHalf; 
    DXS.BufferPositionNotify dxsBPNFull; 
    DXS.Notify Notify; 
    System.Threading.AutoResetEvent ARE; 

    public AudioRecorder(Guid DeviceGuid,DXS.WaveFormat wfWaveFormat,DXS.CaptureEffectDescription[] dxsCapEffectDesc) 
    { 

     dxsCapDev = new Microsoft.DirectX.DirectSound.Capture(DeviceGuid); 
     dxsCapBufferDesc = new Microsoft.DirectX.DirectSound.CaptureBufferDescription(); 
     dxsCapBufferDesc.BufferBytes = CAPTURE_BUFFER_SIZE; 
     dxsCapBufferDesc.Format = wfWaveFormat; 
     dxsCapBufferDesc.WaveMapped = true; 
     dxsCapBufferDesc.CaptureEffectDescription = dxsCapEffectDesc; 
     dxsCapBufferDesc.ControlEffects = true; 


     dxsCapBuffer = new Microsoft.DirectX.DirectSound.CaptureBuffer(dxsCapBufferDesc, dxsCapDev); 

     ARE = new System.Threading.AutoResetEvent(false); 
     dxsBPNHalf = new Microsoft.DirectX.DirectSound.BufferPositionNotify(); 
     dxsBPNFull = new Microsoft.DirectX.DirectSound.BufferPositionNotify(); 
     dxsBPNHalf.Offset = CAPTURE_BUFFER_SIZE/2 - 1; 
     dxsBPNFull.Offset = CAPTURE_BUFFER_SIZE-1; 
     dxsBPNFull.EventNotifyHandle = ARE.SafeWaitHandle.DangerousGetHandle(); 
     dxsBPNHalf.EventNotifyHandle = ARE.SafeWaitHandle.DangerousGetHandle(); 


     dxsBpna = new Microsoft.DirectX.DirectSound.BufferPositionNotify[2]; 
     dxsBpna[0] = dxsBPNHalf; 
     dxsBpna[1] = dxsBPNFull; 

     Notify = new Microsoft.DirectX.DirectSound.Notify(dxsCapBuffer); 
     Notify.SetNotificationPositions(dxsBpna); 

    } 

    public void StartRecording() 
    { 
     if (thrdCapturingThread != null) 
      throw new Exception("Already Recording !"); 
     StopRec = false; 
     thrdCapturingThread = new System.Threading.Thread(Record); 
     thrdCapturingThread.Start(); 


    } 
    private void Record() 
    { 
     DataReceivedHandler drh2 = DataReceivedHandle; 


     dxsCapBuffer.Start(true); 
     byte[] TempBaf = new byte[CAPTURE_BUFFER_SIZE/2]; 
     int StartingOffset = 0; 
     while (dxsCapBuffer.Capturing && !StopRec) 
     { 
      ARE.WaitOne(-1,false); 

       StartingOffset %= CAPTURE_BUFFER_SIZE; 
       TempBaf = (byte[])dxsCapBuffer.Read(StartingOffset, typeof(byte), Microsoft.DirectX.DirectSound.LockFlag.FromWriteCursor, CAPTURE_BUFFER_SIZE/2); 
       StartingOffset += TempBaf.Length; 
       if (drh2 != null) 
        drh2(this, new BMSRecordingEventArgs(TempBaf, false)); 

     } 
     dxsCapBuffer.Stop(); 
     if (drh2 != null) 
      drh2(this, new BMSRecordingEventArgs(TempBaf, true)); 

     mreStillRunning.Set(); 


    } 
    public void StopRecording() 
    { 
     StopRec = true; 
     mreStillRunning.WaitOne(-1,false); 
     thrdCapturingThread = null; 
    } 
} 
+0

遞送數據線程唯一緩衝器,然後一個單獨的線程執行快速拾取與優化的緩衝液系統,以減少使用的時間。它的概念與StringBuilder類似,具有簡單的內存配置文件(刪除部分塊時不需要複製)。所以我認爲麥克風讀取線程正在有效地緩存數據。我緩衝到32MB的內存,並沒有溢出。 –

+0

嘗試使用Managed DirectX進行錄製(甚至更好 - 常規),這相當簡單。沒有代碼,無法幫助你:) – Djole

+0

好的,謝謝。我會盡量在我有時間的情況下實施您的示例(因爲它看起來不像是一個確定的修復)。我想這個問題在OS架構中。我發現在緩衝數據之前將數據轉換爲Double,所以我可以在那裏安全地進行一些迭代。我會先嚐試一下。 –