Direct Sound streaming buffers
My understanding is that when receiving continuous (streaming)audio data via the Direct Sound interface there are tail and header pointers which tell you where you can and cannot read. I need to do some DSP signal processing of an incoming data stream as soon as possible after receiving the data.
I am scanning radio channels and I need to stop the scan as soon as I find the correct data signal. So how quickly I can scan will depend upon how long it takes to detect the signal and how long I have to wait before the received data can be handled.
With the ''waveInxx()'' API functions you don''t get the data until a buffer is filled. Thus the fastest possible scan time I can have is the time for the DSP computations plus the delay of the buffer fill time. I would like to eliminate the second part.
Making the buffer smaller would be one solution but that adds overhead and seems to cause data samples to be missed.
Is the only solution for immediate access to the received data via the primary buffer?
Brian Reinhold
Hi Brian,
"My understanding is that when receiving continuous (streaming)audio data via the Direct Sound interface there are tail and header pointers which tell you where you can and cannot read."
You get a stream - there''s just one object for that (comparable with the primary buffer). But what you do with that is up you. You can use the data of this steam to fill secondary buffers of any size. It is recommended (if you want to do DSP processing on that) to use smaller buffers.
The dsp process is quite simple. You lock the secondary sream, apply the manipulation and unlock it again. It''s obvious that in a realtime application this makes much more sence if the stream is very very small. Myself I used secondary buffers of 2 secs or so, and never ran into problems.
If this does not help, you can post on http://www.superfluxus.de/phpBB
I can place some code there
"My understanding is that when receiving continuous (streaming)audio data via the Direct Sound interface there are tail and header pointers which tell you where you can and cannot read."
You get a stream - there''s just one object for that (comparable with the primary buffer). But what you do with that is up you. You can use the data of this steam to fill secondary buffers of any size. It is recommended (if you want to do DSP processing on that) to use smaller buffers.
The dsp process is quite simple. You lock the secondary sream, apply the manipulation and unlock it again. It''s obvious that in a realtime application this makes much more sence if the stream is very very small. Myself I used secondary buffers of 2 secs or so, and never ran into problems.
If this does not help, you can post on http://www.superfluxus.de/phpBB
I can place some code there
Thanks for the information. But of real importance is how fast can I access data received by the sound card. Two seconds would be way too long. Scan durations are in the order of 100 to 200 milliseconds so you have to be able to detect the signal and STOP the scanning if you find something. If there is a 200 ms delay, by the time the signal is detected, the scanning code would have tuned the radio to another frequency. (One could always return, but you would lose the data stream.)
The terms ''primary'' and ''secondary'' buffers (I assumed from my readings, not experience) are the data on the soundcard memory and then computer memory, or something like that. Maybe it works differently?
It would be great if data received from the soundcard ADC was plopped directly into the primary (and secondary) buffers so there was essentially no delay. But I don''t know. It''s all a blackbox to me and I have not found any descriptions of what these items really are!
Right now I use ''waveInxx()'' functions. If I have double buffers small enough so they flip at 100 baud, Windows can''r handle it. There is a delay every switch and one loses time pulses (one or more sample rate intervals). On my machine, there seems to be no misses when I increase the data size so it flips four times slower (25 baud). I suppose its all in the overhead of Windows sending the MM_WIM_DATA message to the callback after the interrupt.
Brian Reinhold
The terms ''primary'' and ''secondary'' buffers (I assumed from my readings, not experience) are the data on the soundcard memory and then computer memory, or something like that. Maybe it works differently?
It would be great if data received from the soundcard ADC was plopped directly into the primary (and secondary) buffers so there was essentially no delay. But I don''t know. It''s all a blackbox to me and I have not found any descriptions of what these items really are!
Right now I use ''waveInxx()'' functions. If I have double buffers small enough so they flip at 100 baud, Windows can''r handle it. There is a delay every switch and one loses time pulses (one or more sample rate intervals). On my machine, there seems to be no misses when I increase the data size so it flips four times slower (25 baud). I suppose its all in the overhead of Windows sending the MM_WIM_DATA message to the callback after the interrupt.
Brian Reinhold
Hi Brian,
oh, I see the application you're working (my goal was quite different, so I never thought of streaming problems which may derive from the desideratum of a continous steram / connection).
The length of 2 sec is absolutely arbitrary. The buffer is defined in bytes, so you might use some very very small amount, touching the milliseconds (I guess you're only limited by timer exactness, which is for the multimedia timer 20ms, as far as I know.
The concept of primary and secondary buffer is quite simple.
There is just one primary input buffer - and one primary output buffer. - Why is this so? Because the primary buffer represents what you hear (and that means that the primary MUST be the data memory which is displayed by the sound card).
Interestingly enough - you can route such a stream to a 5.1 configuration or to a stereo setting.
The secondary buffers are sound streams which are not mixed together - but they are also hardware accelerated, part of the soundcard memory. Otherwise it would be impossible to do mixing in resaltime, it would result in cracks and clicks etc.
So the soundcard is a complex thing, managing primary buffers (input/output) and additional secondary buffer which are mixed together.
hope this helped
regards MB
[edited by - MB on April 1, 2003 4:17:08 AM]
oh, I see the application you're working (my goal was quite different, so I never thought of streaming problems which may derive from the desideratum of a continous steram / connection).
The length of 2 sec is absolutely arbitrary. The buffer is defined in bytes, so you might use some very very small amount, touching the milliseconds (I guess you're only limited by timer exactness, which is for the multimedia timer 20ms, as far as I know.
The concept of primary and secondary buffer is quite simple.
There is just one primary input buffer - and one primary output buffer. - Why is this so? Because the primary buffer represents what you hear (and that means that the primary MUST be the data memory which is displayed by the sound card).
Interestingly enough - you can route such a stream to a 5.1 configuration or to a stereo setting.
The secondary buffers are sound streams which are not mixed together - but they are also hardware accelerated, part of the soundcard memory. Otherwise it would be impossible to do mixing in resaltime, it would result in cracks and clicks etc.
So the soundcard is a complex thing, managing primary buffers (input/output) and additional secondary buffer which are mixed together.
hope this helped
regards MB
[edited by - MB on April 1, 2003 4:17:08 AM]
Hallo MB!
Dein Englisch ist sehr gut! Ich wunsche daß ich gleich gut Deutsch konnte. Leider so ist es nicht.
When it comes to timing, I was actually thinking of cheating and using the data array received from the sound card as my source of timing; at least for decoding purposes of the digital signal. I figured the sound card sampling rate would be more accurate than the Windows clock.
I get clicks and pops using ''waveOutWrite()'' when the buffer size is smaller than 250 ms in duration. That value maybe machine-dependent. I have seen some programs that use many buffers instead of just two. Creative wrote a windows program for duplex recording/playback with the ''waveInXX()'' and ''waveOutXX()'' fnctions that used 16 buffers. I am not sure what the advantage of using 16 small buffers versus 2 large buffers would be. I would think it would be a disadvantage...many buffers makes for more interrupts and thus overhead.
But even with Direct Sound you need to wait to receive a Windows message telling you that a certain point has been reached in the sound buffer (at least I think that is true). So if you set up your system to tell you to send a message after every N bytes have been received, you find no problem even when N is a small number? I suppose the total buffer size could be much larger than this, but its how often you are able to receive the interrupts before the system can''t handle it that matters.
In the good old days of DOS (though very tedious) you had excellent control of the interrupts since you could get right in there at the time of the interrupt and do what needed to be done.
What do you use recording for? Is it for sound analysis or music of some type?
Brian Reinhold
Dein Englisch ist sehr gut! Ich wunsche daß ich gleich gut Deutsch konnte. Leider so ist es nicht.
When it comes to timing, I was actually thinking of cheating and using the data array received from the sound card as my source of timing; at least for decoding purposes of the digital signal. I figured the sound card sampling rate would be more accurate than the Windows clock.
I get clicks and pops using ''waveOutWrite()'' when the buffer size is smaller than 250 ms in duration. That value maybe machine-dependent. I have seen some programs that use many buffers instead of just two. Creative wrote a windows program for duplex recording/playback with the ''waveInXX()'' and ''waveOutXX()'' fnctions that used 16 buffers. I am not sure what the advantage of using 16 small buffers versus 2 large buffers would be. I would think it would be a disadvantage...many buffers makes for more interrupts and thus overhead.
But even with Direct Sound you need to wait to receive a Windows message telling you that a certain point has been reached in the sound buffer (at least I think that is true). So if you set up your system to tell you to send a message after every N bytes have been received, you find no problem even when N is a small number? I suppose the total buffer size could be much larger than this, but its how often you are able to receive the interrupts before the system can''t handle it that matters.
In the good old days of DOS (though very tedious) you had excellent control of the interrupts since you could get right in there at the time of the interrupt and do what needed to be done.
What do you use recording for? Is it for sound analysis or music of some type?
Brian Reinhold
Hi Brian,
thanks for the compliment, though I fee absolutely deprived when I have to speak english, being uncapable of speaking between the lines...
Back to your problem. 'Cause I forgot nearly everything I knew about stream buffers, I went back to the code I wrote last october-november - and found that I've chosen (because of performace reasons) a very old fashioned way.
First: I did not use a callback structure, but a permanent loop. Much better I think because you can see beforehand that a buffer is near to its closing time.
Then I used two streaming buffers A and B which took just two samples (88200 bytes). When buffer A was closed I appended it to the data sream, and buffer B was locked and the incoming data was routed to it. I guess you know the principle... simple buffer flipping.
I never use WaveOutWrite or other functions of this type. I found that even the classes DirectX gives as sample have their disadvantages. The best was in fact to go to the byte and RIFF level, write the bytes and change the RIFF info later when everything's done. - I guess the reson for Creative to use 16 buffers is quite similiar (but frankly I don't know).
The reason I got into sound programming was much more an artistic ambition. Having workend in the experimental audio I wrote a 3d audio program, just to create the program I always wanted to work with. I was fascinated by EAX and the great possibilities if DirectMusic. It's going to be part of a game engine , but serves as a standalone program also.
Kind of interested what you are looking for with your broadcast program.
Best MB
[edited by - MB on April 1, 2003 8:26:21 AM]
[edited by - MB on April 1, 2003 8:27:06 AM]
thanks for the compliment, though I fee absolutely deprived when I have to speak english, being uncapable of speaking between the lines...
Back to your problem. 'Cause I forgot nearly everything I knew about stream buffers, I went back to the code I wrote last october-november - and found that I've chosen (because of performace reasons) a very old fashioned way.
First: I did not use a callback structure, but a permanent loop. Much better I think because you can see beforehand that a buffer is near to its closing time.
Then I used two streaming buffers A and B which took just two samples (88200 bytes). When buffer A was closed I appended it to the data sream, and buffer B was locked and the incoming data was routed to it. I guess you know the principle... simple buffer flipping.
I never use WaveOutWrite or other functions of this type. I found that even the classes DirectX gives as sample have their disadvantages. The best was in fact to go to the byte and RIFF level, write the bytes and change the RIFF info later when everything's done. - I guess the reson for Creative to use 16 buffers is quite similiar (but frankly I don't know).
The reason I got into sound programming was much more an artistic ambition. Having workend in the experimental audio I wrote a 3d audio program, just to create the program I always wanted to work with. I was fascinated by EAX and the great possibilities if DirectMusic. It's going to be part of a game engine , but serves as a standalone program also.
Kind of interested what you are looking for with your broadcast program.
Best MB
[edited by - MB on April 1, 2003 8:26:21 AM]
[edited by - MB on April 1, 2003 8:27:06 AM]
Hallo MB,
When you say you did a permanent loop, do you mean as a thread or within the message loop (by using ''Peek'' instead of ''GetMessage'')?
If you don''t mind sharing how you did that I would be very grateful. (I am not sure what you mean by "RIFF"...musicians like to call a short fancy sequence they play a RIFF but I think you mean something else!)
I am trying to write the world''s only user friendly DSC controller. DSC = Digital Selective Calling. Its an international standard way for marine radio communications. It is used on HF and VHF and mostly for distress alerts, though its supposed to serve causal purposes as well, but most DSC equipment is so hard to use no one uses it.
The DSC message is coded using FSK (Frequency Shift Keying) which means that bit values are transmitted as two audio tones for a fixed duration of time (100 baud on HF and 1200 baud on VHF). So I need to take the audio signal as it is received and identify the tones as one or zero bits. That''s a bunch of DSP (digital signal processing) stuff which I know only a little bit about. Its a big step from theory to actual practice. Windows programming is also new to me. I''ve only done it since the beginning of the year.
So I am trying to do too much with too little experience. Deal with WIndows, Soundcard handling and Direct Audio or ''waveXX'' stuff (some progress there), and FSK DSP. If I get by those hurdles, I am fine. THe only thing I DO know is how DSC works. Then I can make a user friendly controller. THe marine world could certainly use one!
Brian Reinhold
When you say you did a permanent loop, do you mean as a thread or within the message loop (by using ''Peek'' instead of ''GetMessage'')?
If you don''t mind sharing how you did that I would be very grateful. (I am not sure what you mean by "RIFF"...musicians like to call a short fancy sequence they play a RIFF but I think you mean something else!)
I am trying to write the world''s only user friendly DSC controller. DSC = Digital Selective Calling. Its an international standard way for marine radio communications. It is used on HF and VHF and mostly for distress alerts, though its supposed to serve causal purposes as well, but most DSC equipment is so hard to use no one uses it.
The DSC message is coded using FSK (Frequency Shift Keying) which means that bit values are transmitted as two audio tones for a fixed duration of time (100 baud on HF and 1200 baud on VHF). So I need to take the audio signal as it is received and identify the tones as one or zero bits. That''s a bunch of DSP (digital signal processing) stuff which I know only a little bit about. Its a big step from theory to actual practice. Windows programming is also new to me. I''ve only done it since the beginning of the year.
So I am trying to do too much with too little experience. Deal with WIndows, Soundcard handling and Direct Audio or ''waveXX'' stuff (some progress there), and FSK DSP. If I get by those hurdles, I am fine. THe only thing I DO know is how DSC works. Then I can make a user friendly controller. THe marine world could certainly use one!
Brian Reinhold
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement