OpenAL sink

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

OpenAL sink

Babineau, Denis

Hi, I’m trying to write an audio sink for OpenAL (if such a thing already exists, please point me to it, because I haven’t found it! J ). I’m subclassing GstAudioSink and am a bit confused regarding some of the values passed in the prepare() function (GstRingBufferSpec struct) and would appreciate a bit of direction. From the docs:

 

  guint64  latency_time;        /* the required/actual latency time, this is the

                                * actual the size of one segment and the

                                * minimum possible latency we can achieve. */

  guint64  buffer_time;         /* the required/actual time of the buffer, this is

                                * the total size of the buffer and maximum

                                * latency we can compensate for. */

  gint     segsize;             /* size of one buffer segment in bytes, this value

                                * should be chosen to match latency_time as

                                * well as possible. */

  gint     segtotal;            /* total number of segments, this value is the

                                * number of segments of @segsize and should be

                                * chosen so that it matches buffer_time as

                                * close as possible. */

 

All 4 values are under [in/out] so I don’t know if it’s inputting recommended values with the option of tweaking them? Regarding latency_time/buffer_time, I’m leaving them as defaults (they can be modified thru the properties) and by default I get values of 10,000/0 respectively with my test. Segsize/segtotal I take as “buffer size” and “number of buffers”, with OpenAL I have to pre-allocate buffers and while running I write to the buffer and queue them (and unqueue processed buffers). And so in my test I get 882 segsize and 20 segtotal so I pre-allocate 20 OpenAL buffers and fill/queue them during the write() call but what appears to be happening is that all the buffers gets full before even one buffer gets processed by OpenAL so I end up overrunning my buffers. Should I be stalling the write() call? Also, do those values make sense? When I normally stream a sound in OpenAL (not synced to video) I would allocate fairly large buffers, but not so many (2-3 buffers large enough to keep about 2-3 seconds buffered).  But here from what I understand it’s suggesting I allocate buffers of only a few samples each (i.e. 882 / 4 = 220 samples).

 

At this point I’m not too worried about latency/delays; I’m just trying to get something playing sound so that I get a better feel as to how this interface works.

 

Any input appreciated!

 

Thanks

Denis

CONFIDENTIALITY NOTICE: The contents of this email are confidential
and for the exclusive use of the intended recipient. If you receive this
email in error, please delete it from your system immediately and 
notify us either by email, telephone or fax. You should not copy,
forward, or otherwise disclose the content of the email.

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: OpenAL sink

Tristan Matthews-2
2010/2/1 Babineau, Denis <[hidden email]>

All 4 values are under [in/out] so I don’t know if it’s inputting recommended values with the option of tweaking them?

Have you looked at code in jackaudiosink? It has reasonable defaults. Also, if you need more fine grained control over scheduling and synchronization, your plugin should be derived from GstBaseAudioSink rather than GstAudioSink (see section 20.1 of the plugin writer's guide: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/chapter-other-base.html#section-base-sink). I'm not familiar enough with OpenAL to know if this is really necessary.

Good luck, this would be a welcome addition to gstreamer.

-Tristan

Regarding latency_time/buffer_time, I’m leaving them as defaults (they can be modified thru the properties) and by default I get values of 10,000/0 respectively with my test. Segsize/segtotal I take as “buffer size” and “number of buffers”, with OpenAL I have to pre-allocate buffers and while running I write to the buffer and queue them (and unqueue processed buffers). And so in my test I get 882 segsize and 20 segtotal so I pre-allocate 20 OpenAL buffers and fill/queue them during the write() call but what appears to be happening is that all the buffers gets full before even one buffer gets processed by OpenAL so I end up overrunning my buffers. Should I be stalling the write() call? Also, do those values make sense? When I normally stream a sound in OpenAL (not synced to video) I would allocate fairly large buffers, but not so many (2-3 buffers large enough to keep about 2-3 seconds buffered).  But here from what I understand it’s suggesting I allocate buffers of only a few samples each (i.e. 882 / 4 = 220 samples).

 

At this point I’m not too worried about latency/delays; I’m just trying to get something playing sound so that I get a better feel as to how this interface works.

 

Any input appreciated!

 

Thanks

Denis

CONFIDENTIALITY NOTICE: The contents of this email are confidential
and for the exclusive use of the intended recipient. If you receive this
email in error, please delete it from your system immediately and 
notify us either by email, telephone or fax. You should not copy,
forward, or otherwise disclose the content of the email.

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel




--
Tristan Matthews
email: [hidden email]
web: http://tristanswork.blogspot.com

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: OpenAL sink

Wim Taymans
In reply to this post by Babineau, Denis
On Mon, 2010-02-01 at 11:54 -0400, Babineau, Denis wrote:

> Hi, I’m trying to write an audio sink for OpenAL (if such a thing
> already exists, please point me to it, because I haven’t found it!
> J ). I’m subclassing GstAudioSink and am a bit confused regarding some
> of the values passed in the prepare() function (GstRingBufferSpec
> struct) and would appreciate a bit of direction. From the docs:
>
>  
>
>   guint64  latency_time;        /* the required/actual latency time,
> this is the
>
>                                 * actual the size of one segment and
> the
>
>                                 * minimum possible latency we can
> achieve. */
>
>   guint64  buffer_time;         /* the required/actual time of the
> buffer, this is
>
>                                 * the total size of the buffer and
> maximum
>
>                                 * latency we can compensate for. */
>
>   gint     segsize;             /* size of one buffer segment in
> bytes, this value
>
>                                 * should be chosen to match
> latency_time as
>
>                                 * well as possible. */
>
>   gint     segtotal;            /* total number of segments, this
> value is the
>
>                                 * number of segments of @segsize and
> should be
>
>                                 * chosen so that it matches
> buffer_time as
>
>                                 * close as possible. */
>
>  
>
> All 4 values are under [in/out] so I don’t know if it’s inputting
> recommended values with the option of tweaking them? Regarding
> latency_time/buffer_time, I’m leaving them as defaults (they can be
> modified thru the properties) and by default I get values of 10,000/0
> respectively with my test. Segsize/segtotal I take as “buffer size”
> and “number of buffers”, with OpenAL I have to pre-allocate buffers
> and while running I write to the buffer and queue them (and unqueue
> processed buffers). And so in my test I get 882 segsize and 20
> segtotal so I pre-allocate 20 OpenAL buffers and fill/queue them
> during the write() call but what appears to be happening is that all
> the buffers gets full before even one buffer gets processed by OpenAL
> so I end up overrunning my buffers. Should I be stalling the write()
> call? Also, do those values make sense? When I normally stream a sound
> in OpenAL (not synced to video) I would allocate fairly large buffers,
> but not so many (2-3 buffers large enough to keep about 2-3 seconds
> buffered).  But here from what I understand it’s suggesting I allocate
> buffers of only a few samples each (i.e. 882 / 4 = 220 samples).

You should be stalling the write call when you have filled but not
played buffer_time worth of data. You would likely allocate 20 buffers
of 10ms (like you do) then fill and send each of them. Until OpenAl is
done with a buffer, you can unblock the write and put new data in it.

The reason for the small buffers (10ms) is so that you can achieve lower
latency in live applications (assuming the OpenAL API works by filling
the buffer and then sending it).

Wim

>
>  
>
> At this point I’m not too worried about latency/delays; I’m just
> trying to get something playing sound so that I get a better feel as
> to how this interface works.
>
>  
>
> Any input appreciated!
>
>  
>
> Thanks
>
> Denis
>
>
> CONFIDENTIALITY NOTICE: The contents of this email are confidential
> and for the exclusive use of the intended recipient. If you receive this
> email in error, please delete it from your system immediately and
> notify us either by email, telephone or fax. You should not copy,
> forward, or otherwise disclose the content of the email.
> ------------------------------------------------------------------------------
> The Planet: dedicated and managed hosting, cloud storage, colocation
> Stay online with enterprise data centers and the best network in the business
> Choose flexible plans and management services without long-term contracts
> Personal 24x7 support from experience hosting pros just a phone call away.
> http://p.sf.net/sfu/theplanet-com
> _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel



------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: OpenAL sink

Babineau, Denis
Thanks Wim, it's working now that I block the write when buffers are full. Now I'm looking at properly implementing delay()/reset() but in the process I noticed that I get some OpenAL errors that aren't always consistent. OpenAL is context based with the context being tied to a specific thread (similar to OpenGL), but I noticed that my element gets called from several different threads which may be causing errors. I'm still just using gst-launch so I can't debug properly (printfs with pthread_self()) but here's what I'm seeing:

Thread 1: plugin_init()
Thread 1: open() - context created here, thus bound to this thread
Thread 2: prepare() - buffers allocated here, on a different thread, seems to work but not proper
Thread 1: delay()
Thread 3: write() - yet another thread, again, seems to work but not proper
Thread 2: delay()
Thread 1: reset()

What should I expect as far as threading/synchronization of this AudioSink api? It seems odd to me that prepare()/write() would be done from two different threads and that I get delay() calls that doesn't always come from the same thread. Are those calls at least done synchronously?

Thanks
Denis

-----Original Message-----
From: Wim Taymans [mailto:[hidden email]]
Sent: Monday, February 01, 2010 1:20 PM
To: Discussion of the development of GStreamer
Subject: Re: [gst-devel] OpenAL sink

On Mon, 2010-02-01 at 11:54 -0400, Babineau, Denis wrote:

> Hi, I’m trying to write an audio sink for OpenAL (if such a thing
> already exists, please point me to it, because I haven’t found it!
> J ). I’m subclassing GstAudioSink and am a bit confused regarding some
> of the values passed in the prepare() function (GstRingBufferSpec
> struct) and would appreciate a bit of direction. From the docs:
>
>  
>
>   guint64  latency_time;        /* the required/actual latency time,
> this is the
>
>                                 * actual the size of one segment and
> the
>
>                                 * minimum possible latency we can
> achieve. */
>
>   guint64  buffer_time;         /* the required/actual time of the
> buffer, this is
>
>                                 * the total size of the buffer and
> maximum
>
>                                 * latency we can compensate for. */
>
>   gint     segsize;             /* size of one buffer segment in
> bytes, this value
>
>                                 * should be chosen to match
> latency_time as
>
>                                 * well as possible. */
>
>   gint     segtotal;            /* total number of segments, this
> value is the
>
>                                 * number of segments of @segsize and
> should be
>
>                                 * chosen so that it matches
> buffer_time as
>
>                                 * close as possible. */
>
>  
>
> All 4 values are under [in/out] so I don’t know if it’s inputting
> recommended values with the option of tweaking them? Regarding
> latency_time/buffer_time, I’m leaving them as defaults (they can be
> modified thru the properties) and by default I get values of 10,000/0
> respectively with my test. Segsize/segtotal I take as “buffer size”
> and “number of buffers”, with OpenAL I have to pre-allocate buffers
> and while running I write to the buffer and queue them (and unqueue
> processed buffers). And so in my test I get 882 segsize and 20
> segtotal so I pre-allocate 20 OpenAL buffers and fill/queue them
> during the write() call but what appears to be happening is that all
> the buffers gets full before even one buffer gets processed by OpenAL
> so I end up overrunning my buffers. Should I be stalling the write()
> call? Also, do those values make sense? When I normally stream a sound
> in OpenAL (not synced to video) I would allocate fairly large buffers,
> but not so many (2-3 buffers large enough to keep about 2-3 seconds
> buffered).  But here from what I understand it’s suggesting I allocate
> buffers of only a few samples each (i.e. 882 / 4 = 220 samples).

You should be stalling the write call when you have filled but not
played buffer_time worth of data. You would likely allocate 20 buffers
of 10ms (like you do) then fill and send each of them. Until OpenAl is
done with a buffer, you can unblock the write and put new data in it.

The reason for the small buffers (10ms) is so that you can achieve lower
latency in live applications (assuming the OpenAL API works by filling
the buffer and then sending it).

Wim

>
>  
>
> At this point I’m not too worried about latency/delays; I’m just
> trying to get something playing sound so that I get a better feel as
> to how this interface works.
>
>  
>
> Any input appreciated!
>
>  
>
> Thanks
>
> Denis
>
>
> CONFIDENTIALITY NOTICE: The contents of this email are confidential
> and for the exclusive use of the intended recipient. If you receive this
> email in error, please delete it from your system immediately and
> notify us either by email, telephone or fax. You should not copy,
> forward, or otherwise disclose the content of the email.
> ------------------------------------------------------------------------------
> The Planet: dedicated and managed hosting, cloud storage, colocation
> Stay online with enterprise data centers and the best network in the business
> Choose flexible plans and management services without long-term contracts
> Personal 24x7 support from experience hosting pros just a phone call away.
> http://p.sf.net/sfu/theplanet-com
> _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel



------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
CONFIDENTIALITY NOTICE: The contents of this email are confidential
and for the exclusive use of the intended recipient. If you receive this
email in error, please delete it from your system immediately and
notify us either by email, telephone or fax. You should not copy,
forward, or otherwise disclose the content of the email.
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: OpenAL sink

ved kpl
The prepare() will be called from the streaming thread during caps
negotiation for device setup, whereas the
audiosink creates a separate thread which reads from the
ringbuffer(gst) and writes to the device,
by calling the write() method.
The open() call will be made during state transitions (null->ready) by
the main thread.




On Tue, Feb 2, 2010 at 1:30 AM, Babineau, Denis
<[hidden email]> wrote:

> Thanks Wim, it's working now that I block the write when buffers are full. Now I'm looking at properly implementing delay()/reset() but in the process I noticed that I get some OpenAL errors that aren't always consistent. OpenAL is context based with the context being tied to a specific thread (similar to OpenGL), but I noticed that my element gets called from several different threads which may be causing errors. I'm still just using gst-launch so I can't debug properly (printfs with pthread_self()) but here's what I'm seeing:
>
> Thread 1: plugin_init()
> Thread 1: open() - context created here, thus bound to this thread
> Thread 2: prepare() - buffers allocated here, on a different thread, seems to work but not proper
> Thread 1: delay()
> Thread 3: write() - yet another thread, again, seems to work but not proper
> Thread 2: delay()
> Thread 1: reset()
>
> What should I expect as far as threading/synchronization of this AudioSink api? It seems odd to me that prepare()/write() would be done from two different threads and that I get delay() calls that doesn't always come from the same thread. Are those calls at least done synchronously?
>
> Thanks
> Denis
>
> -----Original Message-----
> From: Wim Taymans [mailto:[hidden email]]
> Sent: Monday, February 01, 2010 1:20 PM
> To: Discussion of the development of GStreamer
> Subject: Re: [gst-devel] OpenAL sink
>
> On Mon, 2010-02-01 at 11:54 -0400, Babineau, Denis wrote:
>> Hi, I’m trying to write an audio sink for OpenAL (if such a thing
>> already exists, please point me to it, because I haven’t found it!
>> J ). I’m subclassing GstAudioSink and am a bit confused regarding some
>> of the values passed in the prepare() function (GstRingBufferSpec
>> struct) and would appreciate a bit of direction. From the docs:
>>
>>
>>
>>   guint64  latency_time;        /* the required/actual latency time,
>> this is the
>>
>>                                 * actual the size of one segment and
>> the
>>
>>                                 * minimum possible latency we can
>> achieve. */
>>
>>   guint64  buffer_time;         /* the required/actual time of the
>> buffer, this is
>>
>>                                 * the total size of the buffer and
>> maximum
>>
>>                                 * latency we can compensate for. */
>>
>>   gint     segsize;             /* size of one buffer segment in
>> bytes, this value
>>
>>                                 * should be chosen to match
>> latency_time as
>>
>>                                 * well as possible. */
>>
>>   gint     segtotal;            /* total number of segments, this
>> value is the
>>
>>                                 * number of segments of @segsize and
>> should be
>>
>>                                 * chosen so that it matches
>> buffer_time as
>>
>>                                 * close as possible. */
>>
>>
>>
>> All 4 values are under [in/out] so I don’t know if it’s inputting
>> recommended values with the option of tweaking them? Regarding
>> latency_time/buffer_time, I’m leaving them as defaults (they can be
>> modified thru the properties) and by default I get values of 10,000/0
>> respectively with my test. Segsize/segtotal I take as “buffer size”
>> and “number of buffers”, with OpenAL I have to pre-allocate buffers
>> and while running I write to the buffer and queue them (and unqueue
>> processed buffers). And so in my test I get 882 segsize and 20
>> segtotal so I pre-allocate 20 OpenAL buffers and fill/queue them
>> during the write() call but what appears to be happening is that all
>> the buffers gets full before even one buffer gets processed by OpenAL
>> so I end up overrunning my buffers. Should I be stalling the write()
>> call? Also, do those values make sense? When I normally stream a sound
>> in OpenAL (not synced to video) I would allocate fairly large buffers,
>> but not so many (2-3 buffers large enough to keep about 2-3 seconds
>> buffered).  But here from what I understand it’s suggesting I allocate
>> buffers of only a few samples each (i.e. 882 / 4 = 220 samples).
>
> You should be stalling the write call when you have filled but not
> played buffer_time worth of data. You would likely allocate 20 buffers
> of 10ms (like you do) then fill and send each of them. Until OpenAl is
> done with a buffer, you can unblock the write and put new data in it.
>
> The reason for the small buffers (10ms) is so that you can achieve lower
> latency in live applications (assuming the OpenAL API works by filling
> the buffer and then sending it).
>
> Wim
>
>>
>>
>>
>> At this point I’m not too worried about latency/delays; I’m just
>> trying to get something playing sound so that I get a better feel as
>> to how this interface works.
>>
>>
>>
>> Any input appreciated!
>>
>>
>>
>> Thanks
>>
>> Denis
>>
>>
>> CONFIDENTIALITY NOTICE: The contents of this email are confidential
>> and for the exclusive use of the intended recipient. If you receive this
>> email in error, please delete it from your system immediately and
>> notify us either by email, telephone or fax. You should not copy,
>> forward, or otherwise disclose the content of the email.
>> ------------------------------------------------------------------------------
>> The Planet: dedicated and managed hosting, cloud storage, colocation
>> Stay online with enterprise data centers and the best network in the business
>> Choose flexible plans and management services without long-term contracts
>> Personal 24x7 support from experience hosting pros just a phone call away.
>> http://p.sf.net/sfu/theplanet-com
>> _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
>
>
>
> ------------------------------------------------------------------------------
> The Planet: dedicated and managed hosting, cloud storage, colocation
> Stay online with enterprise data centers and the best network in the business
> Choose flexible plans and management services without long-term contracts
> Personal 24x7 support from experience hosting pros just a phone call away.
> http://p.sf.net/sfu/theplanet-com
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
> CONFIDENTIALITY NOTICE: The contents of this email are confidential
> and for the exclusive use of the intended recipient. If you receive this
> email in error, please delete it from your system immediately and
> notify us either by email, telephone or fax. You should not copy,
> forward, or otherwise disclose the content of the email.
> ------------------------------------------------------------------------------
> The Planet: dedicated and managed hosting, cloud storage, colocation
> Stay online with enterprise data centers and the best network in the business
> Choose flexible plans and management services without long-term contracts
> Personal 24x7 support from experience hosting pros just a phone call away.
> http://p.sf.net/sfu/theplanet-com
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
>

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel