1
我使用NAudio(但適用於直接閱讀)捕獲麥克風波形數據。看來,如果我的應用程序很忙,它會丟棄/跳過麥克風的一些輸入數據。從麥克風無損閱讀
我已經將閱讀線程設置爲最高優先級,但我在同一時間在其他幾個線程中進行繁重的計算。
有沒有辦法讀取數據無損?
(或者它是無損的,我的錯誤在其他地方?)
我使用NAudio(但適用於直接閱讀)捕獲麥克風波形數據。看來,如果我的應用程序很忙,它會丟棄/跳過麥克風的一些輸入數據。從麥克風無損閱讀
我已經將閱讀線程設置爲最高優先級,但我在同一時間在其他幾個線程中進行繁重的計算。
有沒有辦法讀取數據無損?
(或者它是無損的,我的錯誤在其他地方?)
當我製作一個類似的應用程序,並有類似的問題,事實證明,我需要一個緩衝區,可以保存至少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;
}
}
遞送數據線程唯一緩衝器,然後一個單獨的線程執行快速拾取與優化的緩衝液系統,以減少使用的時間。它的概念與StringBuilder類似,具有簡單的內存配置文件(刪除部分塊時不需要複製)。所以我認爲麥克風讀取線程正在有效地緩存數據。我緩衝到32MB的內存,並沒有溢出。 –
嘗試使用Managed DirectX進行錄製(甚至更好 - 常規),這相當簡單。沒有代碼,無法幫助你:) – Djole
好的,謝謝。我會盡量在我有時間的情況下實施您的示例(因爲它看起來不像是一個確定的修復)。我想這個問題在OS架構中。我發現在緩衝數據之前將數據轉換爲Double,所以我可以在那裏安全地進行一些迭代。我會先嚐試一下。 –