Csound Csound-dev Csound-tekno Search About

[Csnd-dev] Fwd: [openal] Buffer fill callback

Date2017-02-12 20:37
FromAnders Genell
Subject[Csnd-dev] Fwd: [openal] Buffer fill callback

Dear devs!

I posted a question to the OpenAL-soft list about possibility to essentially have AL (or rather alsa through AL in our case) handle rate of performKsmps() runs, which is what we ideally would like to do. I have included below the reply Chris Robinson who more or less is the sole maintainer of OpenAL-soft. 

As I am no programmer I could only partly interpret his reply, other than that it is not possible at the moment. 

I was just wondering if any of you gurus would care to spare a thought on the matter? 

Regards,
Anders

Vidarebefordrat brev:

Från: Chris Robinson <chris.kcat@gmail.com>
Datum: 12 februari 2017 20:55:01 CET
Till: openal mailing list <openal@openal.org>
Ämne: Re: [openal] Buffer fill callback
Svara till: openal mailing list <openal@openal.org>

On 02/11/2017 01:41 AM, Anders Genell wrote:
In some (many?) audio applications the way to avoid hardware buffer
underruns is to have the audio interface driver ask the application
for more data when (part of) a buffer has been consumed. That way
processing rate will essentially be controlled by the audio hardware.
In our case we use Csound under Linux to generate audio. Using the
Csound API we can tell Csound to generate one chunk of audio data at
a time, and by choosing the chunk size to be the same as buffer or
period size things will sync up nicely.

If we want to transfer that audio data to OpenAL-soft buffers,
however, there seem to be a need to poll for buffer fill rate, which
would mean we need to choose an appropriate polling frequency to
ensure buffers are never empty. If I have understood things correctly
this will not sync up as nicely to the audio hardware. In our case,
OpenAL-soft uses the alsa backend, so the hardware buffer callback
would be available in theory. My question is: is there some way to
have OpenAL-soft handle hardware buffer callbacks like that?

Hi.

If I'm understanding right, you're asking if there's a way to have OpenAL Soft run a callback when a buffer is processed and it's time to unqueue+refill+requeue one? If so, then the answer is no. Even if it could, you'd have to treat the callback as being in a "restricted" real-time context; you wouldn't be able to make calls that can block, or otherwise take an indeterminate amount of time (ALSA callbacks are like this too, if not more restricted since they can also happen in a signal handler and you have to worry about re-entrance). Since OpenAL calls don't guarantee real-time or re-entrance safety (they can internally block/wait for some resources to be ready), you'd effectively only be able to signal another thread that it's time to work. So the worker thread is just going to wait around until it sees it can work anyway.

I had thought about adding methods that could allow the application to wait/sleep until some buffers are processed on a source, rather than polling in a loop. But that would only help if you don't have any other processing to do, since you couldn't do anything else while waiting. Otherwise it's best to just check regularly with your main loop.
_______________________________________________
openal mailing list
openal@openal.org
http://openal.org/mailman/listinfo/openal

Date2017-02-22 08:26
FromMichael Gogins
SubjectRe: [Csnd-dev] Fwd: [openal] Buffer fill callback
There are several ways to do this. You will need 2 buffer sizes and 2 buffer indexes. You copy from the spout buffer to the host buffer. When you are at the end of spout you call csoundPerformKsmps and reset the spout index. When you are at the end of the host buffer you make Csound wait and return from the callback. See the CsoundVST code for an example.

Regards,
Mike

On Feb 13, 2017 7:37 AM, "Anders Genell" <anders.genell@gmail.com> wrote:

Dear devs!

I posted a question to the OpenAL-soft list about possibility to essentially have AL (or rather alsa through AL in our case) handle rate of performKsmps() runs, which is what we ideally would like to do. I have included below the reply Chris Robinson who more or less is the sole maintainer of OpenAL-soft. 

As I am no programmer I could only partly interpret his reply, other than that it is not possible at the moment. 

I was just wondering if any of you gurus would care to spare a thought on the matter? 

Regards,
Anders

Vidarebefordrat brev:

Från: Chris Robinson <chris.kcat@gmail.com>
Datum: 12 februari 2017 20:55:01 CET
Till: openal mailing list <openal@openal.org>
Ämne: Re: [openal] Buffer fill callback
Svara till: openal mailing list <openal@openal.org>

On 02/11/2017 01:41 AM, Anders Genell wrote:
In some (many?) audio applications the way to avoid hardware buffer
underruns is to have the audio interface driver ask the application
for more data when (part of) a buffer has been consumed. That way
processing rate will essentially be controlled by the audio hardware.
In our case we use Csound under Linux to generate audio. Using the
Csound API we can tell Csound to generate one chunk of audio data at
a time, and by choosing the chunk size to be the same as buffer or
period size things will sync up nicely.

If we want to transfer that audio data to OpenAL-soft buffers,
however, there seem to be a need to poll for buffer fill rate, which
would mean we need to choose an appropriate polling frequency to
ensure buffers are never empty. If I have understood things correctly
this will not sync up as nicely to the audio hardware. In our case,
OpenAL-soft uses the alsa backend, so the hardware buffer callback
would be available in theory. My question is: is there some way to
have OpenAL-soft handle hardware buffer callbacks like that?

Hi.

If I'm understanding right, you're asking if there's a way to have OpenAL Soft run a callback when a buffer is processed and it's time to unqueue+refill+requeue one? If so, then the answer is no. Even if it could, you'd have to treat the callback as being in a "restricted" real-time context; you wouldn't be able to make calls that can block, or otherwise take an indeterminate amount of time (ALSA callbacks are like this too, if not more restricted since they can also happen in a signal handler and you have to worry about re-entrance). Since OpenAL calls don't guarantee real-time or re-entrance safety (they can internally block/wait for some resources to be ready), you'd effectively only be able to signal another thread that it's time to work. So the worker thread is just going to wait around until it sees it can work anyway.

I had thought about adding methods that could allow the application to wait/sleep until some buffers are processed on a source, rather than polling in a loop. But that would only help if you don't have any other processing to do, since you couldn't do anything else while waiting. Otherwise it's best to just check regularly with your main loop.
_______________________________________________
openal mailing list
openal@openal.org
http://openal.org/mailman/listinfo/openal

Date2017-02-22 11:30
FromMichael Gogins
SubjectRe: [Csnd-dev] Fwd: [openal] Buffer fill callback
Reading your emails again I see there isn't really a callback, but you can still use this idea by running Csound in another thread that runs until OpenAL polls ready. 

On Feb 22, 2017 7:26 PM, "Michael Gogins" <michael.gogins@gmail.com> wrote:
There are several ways to do this. You will need 2 buffer sizes and 2 buffer indexes. You copy from the spout buffer to the host buffer. When you are at the end of spout you call csoundPerformKsmps and reset the spout index. When you are at the end of the host buffer you make Csound wait and return from the callback. See the CsoundVST code for an example.

Regards,
Mike

On Feb 13, 2017 7:37 AM, "Anders Genell" <anders.genell@gmail.com> wrote:

Dear devs!

I posted a question to the OpenAL-soft list about possibility to essentially have AL (or rather alsa through AL in our case) handle rate of performKsmps() runs, which is what we ideally would like to do. I have included below the reply Chris Robinson who more or less is the sole maintainer of OpenAL-soft. 

As I am no programmer I could only partly interpret his reply, other than that it is not possible at the moment. 

I was just wondering if any of you gurus would care to spare a thought on the matter? 

Regards,
Anders

Vidarebefordrat brev:

Från: Chris Robinson <chris.kcat@gmail.com>
Datum: 12 februari 2017 20:55:01 CET
Till: openal mailing list <openal@openal.org>
Ämne: Re: [openal] Buffer fill callback
Svara till: openal mailing list <openal@openal.org>

On 02/11/2017 01:41 AM, Anders Genell wrote:
In some (many?) audio applications the way to avoid hardware buffer
underruns is to have the audio interface driver ask the application
for more data when (part of) a buffer has been consumed. That way
processing rate will essentially be controlled by the audio hardware.
In our case we use Csound under Linux to generate audio. Using the
Csound API we can tell Csound to generate one chunk of audio data at
a time, and by choosing the chunk size to be the same as buffer or
period size things will sync up nicely.

If we want to transfer that audio data to OpenAL-soft buffers,
however, there seem to be a need to poll for buffer fill rate, which
would mean we need to choose an appropriate polling frequency to
ensure buffers are never empty. If I have understood things correctly
this will not sync up as nicely to the audio hardware. In our case,
OpenAL-soft uses the alsa backend, so the hardware buffer callback
would be available in theory. My question is: is there some way to
have OpenAL-soft handle hardware buffer callbacks like that?

Hi.

If I'm understanding right, you're asking if there's a way to have OpenAL Soft run a callback when a buffer is processed and it's time to unqueue+refill+requeue one? If so, then the answer is no. Even if it could, you'd have to treat the callback as being in a "restricted" real-time context; you wouldn't be able to make calls that can block, or otherwise take an indeterminate amount of time (ALSA callbacks are like this too, if not more restricted since they can also happen in a signal handler and you have to worry about re-entrance). Since OpenAL calls don't guarantee real-time or re-entrance safety (they can internally block/wait for some resources to be ready), you'd effectively only be able to signal another thread that it's time to work. So the worker thread is just going to wait around until it sees it can work anyway.

I had thought about adding methods that could allow the application to wait/sleep until some buffers are processed on a source, rather than polling in a loop. But that would only help if you don't have any other processing to do, since you couldn't do anything else while waiting. Otherwise it's best to just check regularly with your main loop.
_______________________________________________
openal mailing list
openal@openal.org
http://openal.org/mailman/listinfo/openal