1

マイクの波のデータをキャプチャするためにNAudioを使用しています(ただし、直接読み取る場合に適用されます)。私のアプリがビジー状態の場合、マイクからの入力データをドロップ/スキップするようです。

読み取りスレッドを最優先に設定しましたが、他のいくつかのスレッドで同時に重い計算を行っています。

データをロスレスで読み取る方法はありますか?
(または、それはロスレスであり、私のバグは他の場所にありますか?)

4

1 に答える 1

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;
    }
}
于 2011-07-13T14:12:04.880 に答える