|
|
| AUDIOSTREAMs not functioning as documented |
|
Thomas Harte
Member #33
April 2000
|
Per the docs (emphasis added): Quote: You must call this function at regular intervals while an audio stream is playing, to provide the next buffer of sample data (the smaller the stream buffer size, the more often it must be called). ... If it returns NULL, the stream is still playing the previous lot of data, so you don't need to do anything. If it returns a value, that is the location of the next buffer to be played The documentation clearly implies a system where one section of sound is being played, and one more is queued. It does this by explicitly using the singular — talking about the next buffer — and claiming that the pointer returned points to the next buffer to be played. So this code:
Should only ever display the number '1'. Otherwise multiple buffers are suddenly available at once, and all but the first one you fill are definitely not, as the documentation promises the next buffer to be played. However, under Windows it displays '6' and under OS X it displays '2'. See the bottom of this post for full details of my machine/OS/etc. Therefore, either the documentation is broken or Allegro is. I would suggest that Allegro is, on the basis that setting things up this way substantially breaks the ability for Allegro programs to maintain a small latency between themselves and the audio output, and where latency can't be avoided the remedy should be to require a larger audio stream buffer rather than to have Allegro lie to the programmer and in so doing not follow the documented behaviour. Comments? Opinions? Am I perhaps wrong? Boring stuff: EDIT: I should add that I've seen the source code of at least one project that assumes that buffers are provided one at a time, an equal amount of time apart, as I believe the documentation implies the will be. I therefore also assume that this is how Allegro used to work and any changes to that will therefore unjustifiably break backwards compatibility if it is agreed that the documentation states that this is their intended method of operation. [My site] [Tetrominoes] |
|
Thomas Fjellstrom
Member #476
June 2000
|
Depending on the config, you get two or more buffers with a SOUNDSTREAM. You have to tweak the size of the buffer you pass, and the allegro.cfg vars for the driver you're using (the alsa config on unix varies greatly between systems, audio hardware, and if theres a pink elephant near by) But yes, the buffers should be ready as soon as allegro is done with them.. so you have to get to filling as soon as allegro is done with them. Its tricky. The api isn't too well done, but its all we have for now. -- |
|
Thomas Harte
Member #33
April 2000
|
Quote: The api isn't too well done, but its all we have for now. And how do you feel about the API not fitting the documentation, especially that the manual claims "If [get_audio_stream_buffer] returns a value, that is the location of the next buffer to be played" but if you don't happen to guess exactly half of the internal Allegro sound buffer size then that usually simply isn't true? [My site] [Tetrominoes] |
|
Thomas Fjellstrom
Member #476
June 2000
|
Well, it is the next buffer, and it wont be half. Depending on the size you ask for and the driver is told to use internally, it could be in 16 pieces or more. What its supposed to do is just return the absolute next buffer thats not been returned yet. Once its returned one, it gets the next if theres one ready (ie: more than two chunks). -- |
|
Thomas Harte
Member #33
April 2000
|
Quote: Well, it is the next buffer In that case, on Windows with the settings I arbitrarily picked there are apparently 6 buffers that are all equally "next to be played". Quote: What its supposed to do is just return the absolute next buffer thats not been returned yet. Once its returned one, it gets the next if theres one ready (ie: more than two chunks). Then you agree that the documentation is incorrect? [My site] [Tetrominoes] |
|
Thomas Fjellstrom
Member #476
June 2000
|
Quote: In that case, on Windows with the settings I arbitrarily picked there are apparently 6 buffers that are all equally "next to be played". They should all be consecutive, so once you fill one, the next one will be ready immediatly if its not been filled yet, or you took too much time getting to it. Quote: Then you agree that the documentation is incorrect? Not sure to be honest. -- |
|
Peter Wang
Member #23
April 2000
|
Quote: Should only ever display the number '1'. Otherwise multiple buffers are suddenly available at once, and all but the first one you fill are definitely not, as the documentation promises the next buffer to be played. If you understand you correctly, you expect get_audio_stream_buffer() to return the buffer directly after the one being played right at the moment you make the call, and only that buffer? Well, I guess that is a documentation bug. What it should say is that there is a queue (ring?) of buffers and get_audio_stream_buffer() returns the next buffer in the queue, and the queue length may be greater than one. Quote: I therefore also assume that this is how Allegro used to work and any changes to that will therefore unjustifiably break backwards compatibility if it is agreed that the documentation states that this is their intended method of operation. I got lost in that sentence somewhere. I will just note that audiostreams have operated in their present state since at least 2000 when the code was entered into version control.
|
|
Thomas Harte
Member #33
April 2000
|
Quote: I got lost in that sentence somewhere. Not surprising. It's possibly the most horrid sentence that ever stood. Quote: If you understand you correctly, you expect get_audio_stream_buffer() to return the buffer directly after the one being played right at the moment you make the call How else would you interpret "If it returns a value, that is the location of the next buffer to be played" (emphasis added)? Anyway, I'm glad this is a documentation issue rather than a genuine implementation flaw. [My site] [Tetrominoes] |
|
Kitty Cat
Member #2,815
October 2002
|
Quote: How else would you interpret "If it returns a value, that is the location of the next buffer to be played"?
The next pending buffer to be played that hasn't been filled. If you have a buffer queue of three, fill the first and start playing it, you have: -- |
|
Thomas Harte
Member #33
April 2000
|
Quote: The next pending buffer to be played that hasn't been filled Right. You've adopted quite different wording to the documentation, so I suggest your post be taken as a vote that the documentation is incorrect. [My site] [Tetrominoes] |
|
Elias
Member #358
May 2000
|
Ok, so would the documentation be any clearer if we append the following to the end? Quote: Note that some drivers use more than two buffers internally, and depending on CPU load, multiple buffers may be ready to be filled at once. Therefore, to minimize the chance of overruns, it is best practice to call get_audio_stream_buffer/free_audio_stream_buffer in a loop until get_audio_stream_buffer returns NULL.
-- |
|
Thomas Harte
Member #33
April 2000
|
I think it might need more fundamental changes than that. The intro says: Quote: You can think of an AUDIOSTREAM structure as a wrapper around two audio buffers. The first thing you do is fill both buffers with sound data and let Allegro play them. Once the first buffer has been played, the second starts, and Allegro lets you know you have to fill the other one (i.e. graphics double buffering applied to sounds too big to fit into memory). Which isn't true, indeed the change you're suggesting explicitly suggests that you can't "think of an AUDIOSTREAM structure as a wrapper around two audio buffers" if you want to minimise the risk of overruns. In addition to fixing that and adding your note, I'd also suggest that the get_audio_stream_buffer documentation is altered, at leas to (changes bolded): Quote: If it returns NULL, the stream is still playing data you've previously provided, so you don't need to do anything. If it returns a value, that is the location of the next buffer that needs to be filled It's not perfect, but I could sit here and obsess over the exact wording all day. [My site] [Tetrominoes] |
|
|