|
View:
New views
10 Messages
—
Rating Filter:
Alert me
|
|
|
Problem with alSourceUnqueueBuffersI am trying to implement a streaming sound engine with OpenAL by uploading small blocks of sound data into buffers as needed instead of the entire sound at once. Doing this requires a lot of buffers queued onto one source so I tried to reuse processed buffers when available instead of creating a new buffer for each block of data. The update loop looks something like this...
alGetSourceiv( source, AL_BUFFERS_PROCESSED, &count ); if ( count ) { alSourceUnqueueBuffers( source, 1, &buffer ); } else { alGenBuffers( 1, &buffer ); } alBufferData( buffer, ... ); alSourceQueueBuffers( source, 1, buffer ); It seems that whenever I use alSourceUnqueueBuffers the source is stopped or otherwise no longer plays the data queued. This causes any sounds longer than the initial few buffers (about two tenths of a second worth) to stop or fail to play entirely. Even if not using the buffer from alSourceUnqueueBuffers or calling alSourcePlay afterwards the problem persists. No errors are being generated. This problem can be circumvented by not calling alSourceUnqueueBuffers and generating new buffers for each sound segment. The questions I have are, is there a significant performance gain from uploading one buffer per source as opposed to uploading segments at a time? Is there some functionality of alSourceUnqueueBuffers that I am missing which is causing this problem? |
|
|
Re: Problem with alSourceUnqueueBuffersHi qartar. First of all, how big are your buffers? They might be too
small. Also, from what I see, you are only unqueuing a single buffer
per iteration, even if count is indicating more than one buffer
processed. You should unqueue and refill every processed buffer in each
loop iteration, else your source is going to run out of audio data
quickly. Hope that helps :)
By the way, is there any reason not to be using buffers in a circular way? Cheers! On Wed, Jun 3, 2009 at 6:36 AM, qartar <qartar@...> wrote:
-- Luis _______________________________________________ Openal mailing list Openal@... http://opensource.creative.com/mailman/listinfo/openal |
|
|
Re: Problem with alSourceUnqueueBuffersThank you for your reply. The buffers are fairly small since they are updated around 60 hz, so approximately 360ish samples per iteration, but I never saw any documentation referring to minimum buffer sizes so I am a little confused. (It may be worth to mention again that no errors are being generated). The function determines how many samples to fill per iteration by checking the current source sample offset against a mixahead value so even if there are extra processed buffers the source does not underrun. As far as circular buffers go, since I haven't seen a way to update a buffer while it is playing (a la DirectSound) I thought this would be close. If you have better solution I would be very interested. |
|
|
Re: Problem with alSourceUnqueueBuffers360 samples is very small for a Buffer, especially if you are playing at 44.1KHz, as that means the Buffers are only about 8 milliseconds in duration. Even if your application is updating the Buffers at 60Hz, the OpenAL implementation is quite likely to be performing mixing in a separate thread that is called less often (more likely 25 times per second). So this would definitely create a scenario where Buffers Processed returns 0 for a while, and then suddenly returns 2 or 3. That might be OK - as long as you have more than 3 Buffers in the queue, and that you immediately unqueue, fill, and requeue all of the buffers (otherwise you will starve the Source of audio data). The Creative Windows OpenAL SDK includes some example code for streaming that might be worth looking at. In general, you will have to have a reasonable amount of data in the Source's Buffer Queue (e.g. at least 100ms if this application is intended to run on many OpenAL implementations on many PCs). This should be split into multiple Buffers (e.g 4 Buffers of 25ms each). When ever you request the numbers of Buffers processed, you should unqueue all of them and requeue them with new audio data. You should also include code that checks that the Source is still playing, and if not, include logic to start it playing again. Dan Creative Labs (UK) Ltd. Notice The information in this message is confidential and may be legally privileged. It is intended solely for the addressee. Access to this message by anyone else is unauthorized. If you are not the intended recipient, any disclosure, copying or distribution of the message, or any action taken by you in reliance on it, is prohibited and may be unlawful. If you have received this message in error, please delete it and contact the sender immediately. Thank you. Creative Labs UK Ltd company number 2658256 registered in England and Wales at Belmont Road, Belmont Place, Maidenhead, Berkshire, SL6 6TB qartar <qartar@...> Sent by: To openal-bounces@op openal@... ensource.creative cc .com Subject Re: [Openal] Problem with 06/03/2009 10:32 alSourceUnqueueBuffers AM Luis-33 wrote: > > Hi qartar. First of all, how big are your buffers? They might be too > small. > Also, from what I see, you are only unqueuing a single buffer per > iteration, > even if count is indicating more than one buffer processed. You should > unqueue and refill every processed buffer in each loop iteration, else > your > source is going to run out of audio data quickly. Hope that helps :) > By the way, is there any reason not to be using buffers in a circular > > Cheers! > Thank you for your reply. The buffers are fairly small since they are updated around 60 hz, so approximately 360ish samples per iteration, but I never saw any documentation referring to minimum buffer sizes so I am a little confused. (It may be worth to mention again that no errors are being generated). The function determines how many samples to fill per iteration by checking the current source sample offset against a mixahead value so even if there are extra processed buffers the source does not underrun. As far as circular buffers go, since I haven't seen a way to update a buffer while it is playing (a la DirectSound) I thought this would be close. If you have better solution I would be very interested. -- View this message in context: http://www.nabble.com/Problem-with-alSourceUnqueueBuffers-tp23845230p23848351.html Sent from the OpenAL - User mailing list archive at Nabble.com. _______________________________________________ Openal mailing list Openal@... http://opensource.creative.com/mailman/listinfo/openal ForwardSourceID:NT0006CABE _______________________________________________ Openal mailing list Openal@... http://opensource.creative.com/mailman/listinfo/openal |
|
|
Re: Problem with alSourceUnqueueBuffers> You should also include code that
> checks that the Source is still playing, and if not, include logic > to start > it playing again. This is why there are no errors returned, by the way. As far as OpenAL is concerned, everything is fine. It runs out of data and then stops the source just like it should. No error. ;-) In summary, make two changes: 1) The implementation should be changed such that it has 100ms or so of data available in multiple buffers (four or so seems "reasonable," but as few as two _should_ work). 2) Detect an "under-run" by looking for streams which have stopped sources. When detected, buffer up a full set of buffers for that source and do a Play on that source. In most products, this should be a very rare occurrence, but may still happen during long disk access or some other operation which stalls the engine for a while. Garin _______________________________________________ Openal mailing list Openal@... http://opensource.creative.com/mailman/listinfo/openal |
|
|
Re: Problem with alSourceUnqueueBuffersThank you again for your replies. You seem to be focusing on buffer underrun issues. I went back to my code and added a check to be sure and it does not seem to be the issue. When a sound is played the engine determines how many samples ahead of the source it should be uploading, usually 100 milliseconds, and uploads that many samples, so on the first iteration 2205 samples are uploaded for a 22050 hz sound file, and then subsequent iterations are performed at approximately 60 hz. This works when not unqueueing buffers, but as soon as I unqueue a buffer, regardless of whether I delete or reuse that buffer, the sound stops playing. |
|
|
Re: Problem with alSourceUnqueueBuffers> Thank you again for your replies. You seem to be focusing on buffer underrun > issues. I went back to my code and added a check to be sure and it does not > seem to be the issue. When a sound is played the engine determines how many > samples ahead of the source it should be uploading, usually 100 > milliseconds, and uploads that many samples, so on the first iteration 2205 > samples are uploaded for a 22050 hz sound file, and then subsequent > iterations are performed at approximately 60 hz. What OpenAL device are you using, and which OS and soundcard? Buffer underrun is the most likely problem I think. In your testing are you able to confirm that Buffers Processed never returns the same number of Buffers that are actually queued on the Source at the moment? For the first iteration how many Buffers are you filling with the 2205 samples? Are you using get playback offset to determine how many samples to fill? I would recommend using a fixed buffer size for the streaming operations rather than trying to compute how many samples have been played. The get sample offset call is tricky to use because it returns an offset from the start of the buffer queue - not the offset in the current buffer. So, I would use, say 4 x 25ms buffers and as and when a buffer is processed, unqueue it, fill it with 25ms of audio data, and requeue it. > This works when not > unqueueing buffers, but as soon as I unqueue a buffer, regardless of whether > I delete or reuse that buffer, the sound stops playing. So if you keep generating, filling, and requeueing new Buffers the Source keeps playing without any problems? Does it play without glitches? Some implementations of OpenAL enable a starved Source to automagically restart playing if the application never actually queries the playback state and just queues new buffers on it. Dan _______________________________________________ Openal mailing list Openal@... http://opensource.creative.com/mailman/listinfo/openal |
|
|
Re: Problem with alSourceUnqueueBuffersOpenAL driver information... Vendor : Creative Labs Inc. Renderer : Software Version : 1.1 Yes, confirmed it just now. One buffer. Yes, with alGetSourceiv( source, AL_SAMPLE_OFFSET, &samplePos ). If I recall correctly, the function returns the sample offset from the beginning of playback, which would include buffers processed, not just the buffers queued. Is there an issue with buffers if they are uploaded with different lengths of data? Yes, if I generate new buffers every iteration instead of trying to reuse processed buffers the source plays with zero problems, this is why I don't think it is an underrun issue. On the other hand, I have put queries before and after the calls to unqueue and queue and it reports that the source is still playing. |
|
|
Re: Problem with alSourceUnqueueBuffersHi, > > What OpenAL device are you using, and which OS and soundcard? > > > > OpenAL driver information... > Vendor : Creative Labs Inc. > Renderer : Software > Version : 1.1 Can you output the actual name of the device being used, e.g. printf("Device is %s\n", alcGetString(deviceHandle, ALC_DEVICE_SPECIFIER)); >From the above information, it could be the "Generic Hardware" or "Generic Software" device. Also, what version of the wrap_oal.dll do you have? > > For the first iteration how many Buffers are you filling with the 2205 > > samples? > > > > One buffer. > > > Are you using get playback offset to determine how many samples to fill? > > I would recommend using a fixed buffer size for the streaming operations > > rather than trying to compute how many samples have been played. The get > > sample offset call is tricky to use because it returns an offset from the > > start of the buffer queue - not the offset in the current buffer. So, I > > would use, say 4 x 25ms buffers and as and when a buffer is processed, > > unqueue it, fill it with 25ms of audio data, and requeue it. > > > > Yes, with alGetSourceiv( source, AL_SAMPLE_OFFSET, &samplePos ). I think there is a fundamental difference in your method of streaming to what I have typically seen. Your method is relying more on get Sample Offset than getting Buffers Processed as a way of determining when and how many samples to requeue on the Source. In the "buffer processed" method, you would need to queue more than one buffer on the first iteration (e.g split the 2205 samples into 4 Buffers). Then completely remove the get sample offset calls and simply wait for a buffer to marked as processed. At which time, you unqueue it, and fill it with the same number of samples, and requeue it. > If I recall > correctly, the function returns the sample offset from the beginning of > playback, which would include buffers processed, not just the buffers > queued. It is the sample offset from the beginning of the *current* queue. e.g If sample offset returns say, 2000 samples, and then you unqueue a (processed) buffer containing 1000 samples, and immediately ask for the sample offset, it will be 1000 samples. Are you taking this into account? > Is there an issue with buffers if they are uploaded with different > lengths of data? There shouldn't be any issues ... but it may cost some memory reallocation, that could otherwise be avoided by keeping the buffer the same size. > > So if you keep generating, filling, and requeueing new Buffers the Source > > keeps playing without any problems? Does it play without glitches? Some > > implementations of OpenAL enable a starved Source to automagically restart > > playing if the application never actually queries the playback state and > > just queues new buffers on it. > > > > Yes, if I generate new buffers every iteration instead of trying to reuse > processed buffers the source plays with zero problems, this is why I don't > think it is an underrun issue. On the other hand, I have put queries before > and after the calls to unqueue and queue and it reports that the source is > still playing. So to be clear - the scenario that works is doing something like this ... 60 times per second ... Get current Sample Offset Compute samples played since last iteration Gen a new buffer and fill it with that number of samples Queue it on Source Or are actually doing an unqueue operation and just ignoring the buffer returned? If you are not unqueuing then the sample offset returned each iteration will always be greater or equal to the value you got on the previous iteration. As soon as you unqueue a buffer in an iteration, the next iteration could see a lower sample offset value (quite likely given the 60 Hz update rate), which will cause issues as you won't queue any new data for a longer period of time. Dan Creative Labs, UK > -- > View this message in context: http://www.nabble.com/Problem-with- > alSourceUnqueueBuffers-tp23845230p23856804.html > Sent from the OpenAL - User mailing list archive at Nabble.com. > > _______________________________________________ > Openal mailing list > Openal@... > http://opensource.creative.com/mailman/listinfo/openal > ForwardSourceID:NT0006CB12 _______________________________________________ Openal mailing list Openal@... http://opensource.creative.com/mailman/listinfo/openal |
|
|
Re: Problem with alSourceUnqueueBuffersIt looks like this was my problem. I've just now added the logic to my code and it seems to be working fine. Thanks for the help! |
| Free embeddable forum powered by Nabble | Forum Help |