Question about Buffer

Oct 25, 2013 at 9:03 PM
How does the buffering work?

For example, if i set 10ms buffer with 2 streams, it will be 20ms total i guess?

But what is best, 20ms with 1 stream or 10ms with 2 streams?
Coordinator
Oct 25, 2013 at 10:35 PM
what buffers are you talking about?
Oct 26, 2013 at 1:09 AM
These:
            BufferNumber.Value = SendStream.NumberOfBuffers = 2;
            BufferLength.Value = SendStream.BufferMilliseconds = 5;
Coordinator
Oct 28, 2013 at 12:05 PM
So SendStream is WaveOut or WaveIn then?
If so, there's no way you'll get it as low as 5ms.
Normally you have two buffers. For playback, one is being filled while the other is being played, then they swap. Same for record. One is being recorded into, while your app is reading out of the other one.
So latency is actually only the size of one buffer when you have two buffers.
Oct 28, 2013 at 9:52 PM
In this it´s for WaveIn.

Ah okay that´s understandable, and well it´s not like i am expecting 5ms.
I am just wondering, what it the optimal setting, is it 2 buffers at 5ms, or 1 buffer at 10ms.

From your standpoint i am guessing 2 buffers at 5ms should be more stable.
Coordinator
Oct 28, 2013 at 9:59 PM
2 buffers. And you'll likely miss buffers if you try as low as 5ms. 50ms is more realistic for the waveIn functions.
Oct 28, 2013 at 10:25 PM
Good. Yeah i know, though i wonder, is there a way to troubleshoot this?

Meaning i can let it run and see oh, 100 buffers got missed during 1 hour, etc?

Cause just listening isn´t that optimal for diagnostics.
Coordinator
Oct 28, 2013 at 10:29 PM
you could try a Stopwatch, and count how many buffers you receive in a given time. Compare that to how many should have been received
Oct 28, 2013 at 10:31 PM
How can i check how many i should receive?
I don´t really have a way to know that, i just change the number/length of the buffers.
Coordinator
Oct 29, 2013 at 12:43 PM
think about it this way, if a buffer is 10ms long, how many buffers are there in 1 second?
Oct 29, 2013 at 10:56 PM
I suck at math, but i would guess 100?
10*100 = 1000, and 1000 milliseconds should be 1 second i think.

But even if i know that, i have no idea to know if the buffer get´s through or is discarded etc, i just hear the constant stream of audio, it´s impossible for me to detect it accurately by listening.
Coordinator
Oct 29, 2013 at 11:19 PM
that's right. so use .NET's stopwatch class to time how long you've recorded for, and in the DataAvailable event, increment a counter.
Oct 30, 2013 at 11:08 AM
So you mean, i should start 2 counters.

1 from the start of the recording, and 1 that runs as long as data is available, and when it´s not, it will simply just pause for that moment, them compare them?

Will have to find a way to do it, but should work, great idea;)
Coordinator
Nov 1, 2013 at 5:29 PM
no I mean just start a .NET stopwatch which is measuring real time, and then have an integer that you increment whenever you get a DataAvailable event. When the stoppedrecording event fires, stop the stopwatch. Then you can compare stopwatch.elapsedmilliseconds with the integer that counted DataAvailable events and see if they match up.
Dec 2, 2013 at 10:34 AM
Edited Dec 2, 2013 at 10:38 AM
Okay i am trying to achieve this, is this correct:
                    while (connect)
                    {
                        TestTimer += 1;
                        Test2.BeginInvoke((Action)(() => { Test2.Text = String.Format("TestTimer: {0} CallTimer: {1}", TestTimer, calltimer.ElapsedMilliseconds / 5); }));
                        ReceivedData = udpReceive.Receive(ref remoteIEP);
                        waveProvider.AddSamples(ReceivedData, 0, ReceivedData.Length);
                        if (Record)
                            waveWriter.Write(ReceivedData, 0, ReceivedData.Length);
                    }
calltimer starts when the call begins and is run at it´s own thread counting real time.
TestTimer as you can see just adds up each loop.

As the buffer is 5ms, i need to divide the calltimer by 5.

I think this is correct, but not sure.


EDIT:

Though when i think of it, as they run on different threads they aren´t even in sync to begin with.
Coordinator
Dec 2, 2013 at 11:21 AM
yes, this is the basic approach I was meaning. You would have a small error due to not starting them at the same instant. But over a long period, you'd find any discrepancies.
Dec 2, 2013 at 1:20 PM
Good, seems to work.

I notice that the problem i have seems to be if i use something else, like rewind skip forward in a video, that takes a bit CPU.
And for some reason stuff like that takes priority over my application, anything that can take some fast CPU power at some point.

I use:

System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.RealTime;

As well as giving the threads highest priority in the application itself.

So do you have any idea why it´s not always at top priority and "pauses" if something needs the CPU for a bit?
(Btw the application uses very little CPU as you can guess, and my CPU is a quadcore 4ghz so performance wise, it doesn´t make sense to me)
Coordinator
Dec 2, 2013 at 1:22 PM
remember .NET is a garbage collected language. The garbage collector will kick in at some point, and none of your code can run during that time. So if your buffers are really small (5ms), there is a good chance you'll miss one
Dec 2, 2013 at 1:24 PM
Well missing one at some point isn´t a problem.

But as i miss much when i use something that takes much CPU is really a problem however.

I am guessing though, it may have to do with the DataAvailable thread, as i can´t control the priority on that one if i remember correctly.