1)As i understood, when we start to receive the messages, the value of delivered_buffers is 8.thus we can't use from the last eight buffers in the queue.isn't it better to add 8 units to requested_buffers?
2)As i uderstood, we can't use from MSC\UST for the first 8 buffers. It's a problem for our program because it hasn't a general pattern.As an example, when we use -w 5 in the shell window, there is no way for buffer 5 to wait for the specified MSC or UST.
3)In the line 258,for compting the waitForUSTInterval, why do we divide the waitForMSCInterval by 2?In the line 355, why do we divide the waitForUSTInterval by 2?
4) In the line 529, what does the trackAudioUstMsc function do?
[ August 25, 2004: Message edited by: ehsan_kamrani ]
We start the transfer after having "pre-rolled" the queue by 8 buffers. So yes, when the first message is received, the "delivered" count is 8. I don't understand why this would prevent your from using the last 8 buffers, though? The buffers are cycled through the queue...
2) Yes, you can use MSC/UST for the first 8 buffers. And if you only plan on transferring 5 buffers (which would be a very very short transfer!), you would probably only pre-roll by 5 buffers (although you still could pre-roll by 8, and simply stop the transfer after 5 -- that would work as well).
3) As the comments suggest, this is only for the purposes of the test/demo program. In order to demonstrate waiting for UST *and* for MSC, we alternate between the two methods -- making the UST interval twice the MSC interval achieves this. No "real" application would need to do this.
4) trackAudioUstMsc is a function in audioUtils.c. As the comments explain, it is used to keep track of time-stamps for the buffers, in order to compute effective transfer rates.
About the question 1, my mean is that we can't receive the reply message for last 8 buffers. As an example, when we request 100 buffers, only 92 buffers are completed-we can receive the reply for 92 buffers.Thus, we don't receive the reply for last 8 buffers. my mean wasn't that we can't pre-roll them in the queue.
[ August 25, 2004: Message edited by: ehsan_kamrani ]
To learn the concepts of the example "memtoaudio", I have created a simple example( I know that in our programs, we can't use from these values.but i think that we can extend these values for our ML programs). please read this example and if there is any error on it, explain me.
We have 2 buffers and fill these buffers with audio data. each buffer has 5 bytes and each audio frame consists of 1 channel and each channel occupies 1 byte.we queue these buffers in the send queue.the value of sample rate is 5. The MSC value for buffer 1 is 1, so the MSC value for buffer 2 is 1+5 = 6. after processing buffer 2, we want to wait for 1 buffer. beacause each buffer consist of 5 audio samples, we must wait for 1 second for each buffer.
buffer2 | buffer 1
after processing buffer1( we want to wait for 1 buffer):
MSC3 =curMSC + ( numBufersInQueue + Idle )*FRAMES = MSC1 +(2+1)*5 = 16.
So we have the following figure:
______Wait For MSC:16 _________MSC2:6
buffer3 | buffer2
after processing buffer2:
MSC4= MSC2 + (2+1)*5 = 21.
______Wait For MSC:21 _______Wait For MSC:16
buffer4 | buffer3
Now we must wait for 1 buffer( one second ).The MSC value is 11 and it is incremented to 16.after that, OpenML starts to process buffer3 and the MSC3( The MSC for buffer 3) would be *11*-not 16.
are these concepts true?
[ October 28, 2004: Message edited by: ehsan_kamrani ]
sorry I didn't see your posted from August 25. You are correct -- the way this demo program is structured, when "x" buffers are requested, only "x-preroll" are actually received and processed. If this were a problem, one possible fix would be to use to use "returned_buffers" instead of "delivered_buffers" in the loop control.
But in a real-life program, I think end-of-loop would be determined differently: either by time, or perhaps as a result of user action (pressing the "STOP" button, for instance). These demo programs are a bit contrived, in order to keep them simple.
As for your recent question -- I think your math is essentially correct. The MSC increments once per frame; so if your buffers contain 5 frames each, there will be a difference of 5 in the MSCs associated with each buffer.
What is perhaps a bit confusing is that you want to 'wait for MSC'. It seems from your example that you really want to be waiting on the message queue -- ie, you don't wait for a specific MSC to happen, but rather you wait for a message to come back from ML with a buffer ready for processing. This buffer will contain the MSC you are expecting (if it doesn't, then there were dropped frames -- your application should be prepared for this).
Now the spec mentions wait predicates (page 97) -- ML_WAIT_FOR_AUDIO_MSC. But this is a bit different: this will stall your buffer until the specified MSC comes around. That means there will be gaps in the frames you capture (ie: ML will not capture frames that come before the MSC you have requested). This would typically be used only once, at the start of a transfer, to achieve synchronisation. I don't think you would use these predicates inside your buffer processing loop.
ok. you told that: It seems from your example that you really want to be waiting on the message queue. so i must clear my example. Again if it persists to be an error,explain me.
ML starts to process the buffer 2.after processing this buffer, It's MSC is 6, so the MSC value for the end frame of this buffer is 10.application receives this buffer and sets the value of ML_WAIT_FOR_AUDIO_MSC to 21( 6+(2+1)*5 )--So for computhing the value of ML_WAIT_FOR_AUDIO_MSC for buffer 4, i have used from the MSC value of buffer2.Now we want to process buffer 3 and know that the ML_WAIT_FOR_AUDIO_MSC value of this buffer is 16. But after processing the previouse buffer( buffer2 ), the MSC value for the end frame of buffer 2 was 10, so we expect that MSC continue with the value of 11. ML increments 11 to 12,13,...,15.for the vlaue of 16, the ML start to process buffer3.BUT at this time it set the MSC value of this buffer to 11(not 16 ).The reason is that if ML set the MSC value of this buffer to 16, the MSC value for the end frame of this buffer would be 20 and buffer4 doesn't wait for 1 second( we had adjusted the ML_WAIT_FOR_AUDIO_MSC value of buffer 4 to 21, So it doesn't wait ); But For the MSC value of 11 for buffer 3, buffer4 can wait( After ML processes the buffer3, MSC is started with 16 and ML increments it to 21 and exactly at this time, the buffer4 is processed.But again the MSC value of buffer4 isn't 21 and is 16 )
So i think that we have 2 types of MSC: one of them are used to increment only and are used for wait messages(ML_WAITE_FOR_AUDIO_MSC) and one of them are incremented for each frame that is processed.
OK, now I understand... you're basing this on the example of 'memtoaudio.c'. You must understand that this is a completely contrived sample program, that doesn't attempt to do anything useful with the WAIT predicates. I seriously doubt any useful application would ever do something like this.
But anyway, let's assume that this is really what we want to do. In your example, when ML starts processing buffer 3, it will set the MSC to 16, *not* 11. The setting of the MSC is dependent *only* on the number of samples that have flowed through the jack. Nothing else affects it (so in particular, it doesn't matter what the application has used as values for WAIT_FOR_AUDIO_MSC -- that will not change the current value of the MSC).
What will happen in this case is that there won't actually be a 1-second pause between buffer 3 and buffer 4. When buffer 3 is finished, the MSC will indeed be at 21, and buffer 4 will immediately be processed.
This is not a problem in ML, this is a bug in the application. If it really wanted to wait 1 second between *each* buffer, it should have taken that into account when it computed the MSC value to wait for in buffer 4 -- it should have computed 26, not 21.
The 'memtoaudio' sample program does not need to do this, because it does not attempt to wait between each sample -- it only waits every so often, as specified by the '-w' command-line argument. (But if the user chose a value that were too small for this setting, a value that would cause waits to overlap, then the sample app would have the same bug as your hypothetical code).