C# DirectSound - Capture buffers not continuous

Posted by Wizche on Stack Overflow See other posts from Stack Overflow or by Wizche
Published on 2009-10-25T14:11:38Z Indexed on 2010/06/08 1:02 UTC
Read the original article Hit count: 472

Filed under:
|
|
|
|

Hi,

I'm trying to capture raw data from my line-in using DirectSound.

My problem is that, from a buffer to another the data are just inconsistent, if for example I capture a sine I see a jump from my last buffer and the new one. To detected this I use a graph widget to draw the first 500 elements of the last buffer and the 500 elements from the new one: Snapshot

I initialized my buffer this way:

   format = new WaveFormat {
            SamplesPerSecond = 44100,
            BitsPerSample = (short)bitpersample,           
            Channels = (short)channels,
            FormatTag = WaveFormatTag.Pcm
        };

        format.BlockAlign = (short)(format.Channels * (format.BitsPerSample / 8));
        format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlign;

        _dwNotifySize = Math.Max(4096, format.AverageBytesPerSecond / 8);
        _dwNotifySize -= _dwNotifySize % format.BlockAlign;
        _dwCaptureBufferSize = NUM_BUFFERS * _dwNotifySize; // my capture buffer
        _dwOutputBufferSize = NUM_BUFFERS * _dwNotifySize / channels; // my output buffer

I set my notifications one at half the buffer and one at the end:

     _resetEvent = new AutoResetEvent(false);
        _notify = new Notify(_dwCapBuffer);

        bpn1 = new BufferPositionNotify();
        bpn1.Offset = ((_dwCapBuffer.Caps.BufferBytes) / 2) - 1;
        bpn1.EventNotifyHandle = _resetEvent.SafeWaitHandle.DangerousGetHandle();
        bpn2 = new BufferPositionNotify();
        bpn2.Offset = (_dwCapBuffer.Caps.BufferBytes) - 1;
        bpn2.EventNotifyHandle = _resetEvent.SafeWaitHandle.DangerousGetHandle();

        _notify.SetNotificationPositions(new BufferPositionNotify[] { bpn1, bpn2 });

        observer.updateSamplerStatus("Events listener initialization complete!\r\n");

And here is how I process the events.

/* Process thread */ private void eventReceived() { int offset = 0; _dwCaptureThread = new Thread((ThreadStart)delegate {

            _dwCapBuffer.Start(true);

            while (isReady)
            {
                _resetEvent.WaitOne(); // Notification received
                /* Read the captured buffer */
                Array read = _dwCapBuffer.Read(offset, typeof(short), LockFlag.None, _dwOutputBufferSize - 1);

                observer.updateTextPacket("Buffer: " + count.ToString() + " # " + read.GetValue(read.Length - 1).ToString() + " # " + read.GetValue(0).ToString() + "\r\n");
                /* Print last/new part of the buffer to the debug graph */
                short[] graphData = new short[1001];
                Array.Copy(read, graphData, 1000);

                db.SetBufferDebug(graphData, 500);
                observer.updateGraph(db.getBufferDebug());



                offset = (offset + _dwOutputBufferSize) % _dwCaptureBufferSize;

                /* Out buffer not used */
                /*_dwDevBuffer.Write(0, read, LockFlag.EntireBuffer);

                _dwDevBuffer.SetCurrentPosition(0);
                _dwDevBuffer.Play(0, BufferPlayFlags.Default);*/

            }

            _dwCapBuffer.Stop();
        });
        _dwCaptureThread.Start();

    }

Any advise? I'm sure I'm failing somewhere in the event processing, but I cant find where.

I had developed the same application using the WaveIn API and it worked well.

Thanks a lot...

© Stack Overflow or respective owner

Related posts about c#

Related posts about api