ALC_ENUMERATE_ALL_EXT and pluggable sound devices

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Guilherme Balena Versiani :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

Day by day, pluggable devices become even more popular. They are cheap
and very attractive for mobile users. Some of pluggable USB sound
devices have good quality. For this reason, it is not suitable anymore
to be obliged to restart an application (or a game) after connecting a
device to be able to use it... And I think that  ALC_ENUMERATE_ALL_EXT
extension should reflect devices changes of the system.

Regarding the support of pluggable devices, I tried to prefix the
following strings with the name of an USB sound device, respectively,
"X-Fi on", "Audigy on", "Generic Hardware on", "Generic Software on",
"DirectSound3D on", "DirectSound on", and "MMSYSTEM on", then calling
alcOpenDevice a second time after the application has been started to
change the current OpenAL context to the USB sound device, but I had no
success doing that. I don't know if there is another way to overcome
this limitation.

A second problem was that I could't list the current connected USB
device by using ALC_ALL_DEVICES_SPECIFIER. Inspecting some OpenAL code
in SVN (specifically the Windows Router code), I discovered that the
variables g_pDeviceList, g_pCaptureDeviceList and g_pAllDevicesList are
initialized only once, in the occurrence of calling opening functions
like alcOpenDevice (see the function BuildDeviceList). I personally
tried to change the code to force a reinitialization of the structures
every time the function BuildDeviceList was called, but I had no success
when trying to select them afterwards (the device was listed, but I
couldn't use it; the alcOpenDevice issued error opening the device).

Do you see any solution for this in the OpenAL roadmap? Or this
"feature" should be implemented elsewhere?

Best regards,

-- Guilherme Balena Versiani.
_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Jason Daly :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Guilherme Balena Versiani wrote:
> Do you see any solution for this in the OpenAL roadmap? Or this
> "feature" should be implemented elsewhere?
>  

Look in the archives for the thread about the new ALC_EXT_disconnect
extension.  It's been implemented (at least partly) in the GIT trunk of
openal-soft.

--"J"

_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Daniel PEACOCK :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message





Hi,

> Day by day, pluggable devices become even more popular. They are cheap
> and very attractive for mobile users. Some of pluggable USB sound
> devices have good quality. For this reason, it is not suitable anymore
> to be obliged to restart an application (or a game) after connecting a
> device to be able to use it... And I think that  ALC_ENUMERATE_ALL_EXT
> extension should reflect devices changes of the system.
>
> A second problem was that I could't list the current connected USB
> device by using ALC_ALL_DEVICES_SPECIFIER. Inspecting some OpenAL code
> in SVN (specifically the Windows Router code), I discovered that the
> variables g_pDeviceList, g_pCaptureDeviceList and g_pAllDevicesList are
> initialized only once, in the occurrence of calling opening functions
> like alcOpenDevice (see the function BuildDeviceList).

I agree that this is a problem that needs to be solved.  The reason why
these variables are initialized once is purely as an optimization to
prevent repeated loading and unloading of DLLs.  However, I think you are
probably right - it would be better to always get an up-to-date list of
available devices when calling the enumerate calls (ALC_DEVICE_SPECIFIER
and ALC_ALL_DEVICES_SPECIFIER).

The tricky part is, perhaps, how an application knows that it should
refresh the available devices.  e.g. An application should definitely not
keep calling an enumerate function just to see if anything is different -
that would be really slow.

Ideally if the Router detected a change of audio devices, then it could set
a flag that enables a refresh of the device lists on the *next* call to an
enumerate function.  (We could even add a new function that the application
can call to determine if the device list has potentially changed).

Unfortunately I don't know of any reliable way on Windows XP and below of
getting a notification that new audio hardware has appeared (or
disappeared).  There are methods of doing that - but I believe they only
work if the application has the focus.   On Vista (and presumably Win7)
there are new methods for dealing with this that work really well.

I would imagine that an OpenAL game / application would probably only make
device enumeration calls at initialization time, and then at some time that
was at the user's request - e.g. if the user goes to the "Audio Options".
That would make sense to me ... e.g. a user launches a game, then plugs in
their USB headset, and then goes to the audio options screen to select them
as his output device.

If that is the most likely scenario, then simply updating the router to
always offer an up-to-date list of devices in response to enumerate calls
may be sufficient.

> I personally
> tried to change the code to force a reinitialization of the structures
> every time the function BuildDeviceList was called, but I had no success
> when trying to select them afterwards (the device was listed, but I
> couldn't use it; the alcOpenDevice issued error opening the device).

I'll take a look at the code - it's been a while!

> Do you see any solution for this in the OpenAL roadmap? Or this
> "feature" should be implemented elsewhere?

I think it could potentially be added in the very near future.

Dan
Creative Labs, UK

_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Ryan C. Gordon-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Daniel PEACOCK wrote:

>
>
>
> Hi,
>
>> Day by day, pluggable devices become even more popular. They are cheap
>> and very attractive for mobile users. Some of pluggable USB sound
>> devices have good quality. For this reason, it is not suitable anymore
>> to be obliged to restart an application (or a game) after connecting a
>> device to be able to use it... And I think that  ALC_ENUMERATE_ALL_EXT
>> extension should reflect devices changes of the system.
>>
>> A second problem was that I could't list the current connected USB
>> device by using ALC_ALL_DEVICES_SPECIFIER. Inspecting some OpenAL code
>> in SVN (specifically the Windows Router code), I discovered that the
>> variables g_pDeviceList, g_pCaptureDeviceList and g_pAllDevicesList are
>> initialized only once, in the occurrence of calling opening functions
>> like alcOpenDevice (see the function BuildDeviceList).
>
> I agree that this is a problem that needs to be solved.  The reason why
> these variables are initialized once is purely as an optimization to
> prevent repeated loading and unloading of DLLs.  However, I think you are
> probably right - it would be better to always get an up-to-date list of
> available devices when calling the enumerate calls (ALC_DEVICE_SPECIFIER
> and ALC_ALL_DEVICES_SPECIFIER).
>
> The tricky part is, perhaps, how an application knows that it should
> refresh the available devices.  e.g. An application should definitely not
> keep calling an enumerate function just to see if anything is different -
> that would be really slow.
>
> Ideally if the Router detected a change of audio devices, then it could set
> a flag that enables a refresh of the device lists on the *next* call to an
> enumerate function.  (We could even add a new function that the application
> can call to determine if the device list has potentially changed).

Shouldn't the router just delegate this responsibility to the actual AL
implementation? Once it picks a lowlevel implementation it probably
shouldn't ever pick a new one. But if a given implementation handles
ALC_EXT_disconnect, then it should do all the work.

So a hardware-specific AL does its thing, and if it only handles a chip
welded to the motherboard, it doesn't expose ALC_EXT_disconnect. If
it's, say, a generic DirectSound implementation, it handles the
extension, and deals with USB devices coming and going.

No changes to the router needed, no constant rechecking of various DLLs.
It seems reasonable to me.

--ryan.

_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Guilherme Balena Versiani :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Comments inline.

Ryan C. Gordon wrote:
>> The tricky part is, perhaps, how an application knows that it should
>> refresh the available devices.  e.g. An application should definitely
>> not
>> keep calling an enumerate function just to see if anything is
>> different -
>> that would be really slow.
I think this is a simple answer. When you commonly enumerate the
available devices? On the configuration menu of you software (normally
you must open some kind of configuration panel on your software to
change the render/capture device). This way, a way to solve this is to
reinitialize the list every time you call:

    - alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER), or
    - alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER)

What do you think? The current problem is that the OpenAL driver
implementation (not the Router) is implemented to save the device names
in the same way the Router is. I changed the Router in a way that the
list is resetted every time the above functions was called, but I saw
same device name "ghosts" in enumeration...

A more complex way to do this is to monitor the USB bus... Every time a
device is connected or disconnected, you reset the device lists.

> Shouldn't the router just delegate this responsibility to the actual
> AL implementation? Once it picks a lowlevel implementation it probably
> shouldn't ever pick a new one. But if a given implementation handles
> ALC_EXT_disconnect, then it should do all the work.
I think this could be a good option, but the ALX_EXT_disconnect
extension does not explicitly require this behavior, and so the
implementors can't trust on it... It should be implemented in a more
robust way, in such a way the implementors don't get confused about what
will happen after this OpenAL call.

Regards,

-- Guilherme Balena Versiani.
_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Ryan C. Gordon-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> I think this could be a good option, but the ALX_EXT_disconnect
> extension does not explicitly require this behavior, and so the
> implementors can't trust on it... It should be implemented in a more
> robust way, in such a way the implementors don't get confused about what
> will happen after this OpenAL call.

ALC_EXT_disconnect says that you find out about new devices by
reenumerating.

I don't really know that we need to set a flag to alert apps (or the
router) that the device list has changed. This code isn't really a
killer if you run it once once every five seconds (or even once a frame)...

   // ignore that C string funcs fail on the null-separated list for now.
   current_devices = alcGetString(NULL,ALC_DEVICE_SPECIFIER);
   if (strcmp(current_devices, previous_devices) != 0) {
      // handle device list change here, if for some reason you need to.
      free(previous_devices);
      previous_devices = strdup(current_devices);
   }


--ryan.
_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Stephen A. :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, 2009-09-18 at 00:43 -0400, Ryan C. Gordon wrote:

> > I think this could be a good option, but the ALX_EXT_disconnect
> > extension does not explicitly require this behavior, and so the
> > implementors can't trust on it... It should be implemented in a more
> > robust way, in such a way the implementors don't get confused about what
> > will happen after this OpenAL call.
>
> ALC_EXT_disconnect says that you find out about new devices by
> reenumerating.
>
> I don't really know that we need to set a flag to alert apps (or the
> router) that the device list has changed. This code isn't really a
> killer if you run it once once every five seconds (or even once a frame)...

Yes it *is* a killer, because string allocations engage the GC in
managed languages  (yes, there is stuff other than C/C++ that relies on
OpenAL). Such an approach would be completely unsuitable for such
environments.

Besides, why allocate a new string every 5 seconds when you could just
say:

if (alcGetBoolean(NULL, ALC_DEVICE_LIST_CHANGED))
{
    // retrieve device list
}

?

>
>    // ignore that C string funcs fail on the null-separated list for now.
>    current_devices = alcGetString(NULL,ALC_DEVICE_SPECIFIER);
>    if (strcmp(current_devices, previous_devices) != 0) {
>       // handle device list change here, if for some reason you need to.
>       free(previous_devices);
>       previous_devices = strdup(current_devices);
>    }
>
>
> --ryan.
> _______________________________________________
> Openal-devel mailing list
> Openal-devel@...
> http://opensource.creative.com/mailman/listinfo/openal-devel

_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Ryan C. Gordon-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> Yes it *is* a killer, because string allocations engage the GC in
> managed languages  (yes, there is stuff other than C/C++ that relies on
> OpenAL). Such an approach would be completely unsuitable for such
> environments.

You only do an allocation when the device list changes in my example. If
you can't handle that, you need a better garbage collector.  :)

--ryan.

_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Stephen A. :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, 2009-09-18 at 12:21 -0400, Ryan C. Gordon wrote:
> > Yes it *is* a killer, because string allocations engage the GC in
> > managed languages  (yes, there is stuff other than C/C++ that relies on
> > OpenAL). Such an approach would be completely unsuitable for such
> > environments.
>
> You only do an allocation when the device list changes in my example. If
> you can't handle that, you need a better garbage collector.  :)

1. You need an allocation whenever you cross heap boundaries (i.e. pass
an unmanaged string to a managed environment). This goes deeper than the
specific GC implementation: by definition, a GC may not touch unmanaged
memory.

2. Most modern environments work on unicode rather than ASCII, which
involves an allocation *and* a translation.

I am sorry, but using strcmp just to check a boolean flag is bad API
design (not to mention inefficient, idiomatic and unportable). It might
be me, but I really cannot see what advantage you think it confers over
a plain boolean query.

_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Guilherme Balena Versiani :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Stefanos A. wrote:

> Besides, why allocate a new string every 5 seconds when you could just
> say:
>
> if (alcGetBoolean(NULL, ALC_DEVICE_LIST_CHANGED))
> {
>     // retrieve device list
> }
>
> ?
>  

I don't agree with this approach. But let me explain first why I am
saying this below.

Let me divide the pluggable devices problem:

  1) There should have some mechanism to reset the device listing to get
any new device connected or disconnected from the system.
  2) There are applications that needs to know if some new device was
connected.

I think the first problem should be solved by just calling
alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER) once again. The
application should not expect to maintain the same listing if you call
alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER) a second time... If the
application does not like to get devices changes, then it just calls
alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER) once, in the
initialization of the program. This call (enumeration) does not need to
be reentrant, so the solution is very simple... I don't like to rely on
an extension, that can be implemented or not by the current installed
OpenAL driver, to use something that IS NEEDED by my application or game.

The second problem could be solved by inspecting the USB bus (or
FireWire, etc) using some kind of O.S. API. But IMHO, OpenAL itself
should not be responsible for this, as this activity is very complex, if
you want to implement an efficient approach (the devices API is very
different between operating systems). But if someone wants to develop
this mechanism, I think you can do something like:

    void my_callback(...) {
        ...
        alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
        ...
    }

    alpnpMonitorDevices(&my_callback);

Why I does not like the proposed solutions:

    1) Stefanos solution ( alcGetBoolean(ALC_DEVICE_LIST_CHANGED) ): you
need to make polling on your program, even if you have a more robust
implementation in lower-level. For example, tomorrow you find that is
more simpler and have less cost to receive some kind of system
notification (that is available on most of current operating systems) in
the event of a device connection.
    2) Ryan solution ( new memory allocated on the return of
alcGetString function ): you will broke the behavior of the function, so
old code implementations will start to leak memory after this change.

I would like to receive comments about the above proposal and why you
couldn't adopt it (I don't know deeply which kind of requirements are
involved in alcGetString API).

Regards,

-- Guilherme Balena Versiani.
_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Chris Robinson-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Friday 18 September 2009 11:28:49 am Guilherme Balena Versiani wrote:

> Stefanos A. wrote:
> > Besides, why allocate a new string every 5 seconds when you could just
> > say:
> >
> > if (alcGetBoolean(NULL, ALC_DEVICE_LIST_CHANGED))
> > {
> >     // retrieve device list
> > }
> >
> > ?

A problem may be in situations where the implementation can't properly
retrieve messages from the OS/sound API about device changes. In such cases,
even getting a boolean about device changes may incur a reprobing of devices
anyway. Sure, you may save on not having to pass the string back to the
program, but I think that's comparatively minor compared to the work already
done.

>     2) Ryan solution ( new memory allocated on the return of
> alcGetString function ): you will broke the behavior of the function, so
> old code implementations will start to leak memory after this change.

The string(s) returned by alcGetString/alGetString are controlled by OpenAL.
When OpenAL frees that memory, it's gone.. the app doesn't need to do anything
to it. And apparently it's already not guaranteed that successive calls to
retrieve the device list will return the same memory.

For languages with GC, I don't see why it wouldn't catch the references to the
old strings being lost when a new set is allocated and given to the app,
initiating a background cleanup of them.


FWIW, I don't think it's that bad of an idea to just retrieve the list every
few seconds. If the cost of alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER) is
too high, then can't you run it in a background thread? Something like:

volatile bool ListUpdated = false;
thread 1:
...app loop...
    if(ListUpdated) {
        lock(&device_update_mutex);
        copy_strings(MyInternalList, StringsFromAL);
        ListUpdated = false;
        unlock(&device_update_mutex);
        ListUpdated();
    }
...end...

thread 2:
   while(!KillMeNow) {
       lock(&device_update_mutex);
       StringsFromAL = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
       ListUpdated = true;
       unlock(&device_update_mutex);
       Sleep(1000);
   }

Then all the reprobing and extra allocation/conversation necessary will happen
away from your main loop, so it should continue on at full speed. The cost to
your main loop would be every second or so just having a copy and whatever
updating you need to do to have the new internal list used.

Additionally, if you wanted, thread 2 could do a compare between the new
strings from AL against MyInternalList, and only mark ListUpdated if they
differ. Then your main loop wouldn't incur any cost unless the devices
actually changed.
_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Ryan C. Gordon-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Shoot, I wrote a big reply and Thunderbird ate it. I'll try again...

> Let me divide the pluggable devices problem:

This is a good distinction.

>   1) There should have some mechanism to reset the device listing to get
> any new device connected or disconnected from the system.

ALC_EXT_disconnect specifies this to be alcGetString().

>   2) There are applications that needs to know if some new device was
> connected.

It might be useful for an extension to supply this as an optimization,
over re-parsing the device list (scripting languages aside, even).

> The second problem could be solved by inspecting the USB bus (or
> FireWire, etc) using some kind of O.S. API. But IMHO, OpenAL itself
> should not be responsible for this, as this activity is very complex, if
> you want to implement an efficient approach (the devices API is very
> different between operating systems). But if someone wants to develop
> this mechanism, I think you can do something like:

As the mechanism is platform-specific, it's exactly what _should_ be
abstracted into OpenAL.

>     1) Stefanos solution ( alcGetBoolean(ALC_DEVICE_LIST_CHANGED) ): you
> need to make polling on your program, even if you have a more robust
> implementation in lower-level. For example, tomorrow you find that is
> more simpler and have less cost to receive some kind of system
> notification (that is available on most of current operating systems) in
> the event of a device connection.

(See my notes below.)

>     2) Ryan solution ( new memory allocated on the return of
> alcGetString function ): you will broke the behavior of the function, so
> old code implementations will start to leak memory after this change.

My solution doesn't require allocation. The AL only promises (in
ALC_EXT_disconnect) that the pointer will remain valid until the next
call to alcGetString(), but it might return a pointer to the same static
internal buffer each time. If it wants to return a new string, it can
take that opportunity to free the previous result, as it doesn't need to
keep it around any more.

My example was application code, and it could employ a static buffer,
too, and never allocate at all.

In either case, it doesn't imply a leak in legacy code.

> I would like to receive comments about the above proposal and why you
> couldn't adopt it (I don't know deeply which kind of requirements are
> involved in alcGetString API).

I think if we're going to get a fight about transferring a string
between C code and a managed language, there's going to be war about
adding callbacks.

That being said, there are uses for callbacks. If we ever did some sort
of DSP pipeline like CoreAudio's AudioUnit API, we'd either need to
create a "shader language" (gasp!) or supply a callback mechanism.

But device notification is not a low-latency operation. In treating it
as an event, it's nothing like notifying the app of mouse input. If a
user plugs in a USB audio device, you could very easily run hundreds of
frames before they've even looked back up at the screen...and in any
case, it'll be several seconds between when they plug the device in and
when the OS configures it enough to let OpenAL know it has become
available. So this doesn't need to report it to the app quickly.

In such a case, checking for new devices once a frame (or once every X
seconds) isn't unreasonable.

Now I'll admit, I threw a hissy-fit about using null chars in the device
enumeration list because of what it does to managed languages that have
to deal with a strange string format. So I'm not against adding a way to
tell them they have a new device without regrabbing the device list string.

Here are my notes about this format...

     alcGetBoolean(ALC_DEVICE_LIST_CHANGED, &trueOrFalse);

- There's no alcGetBoolean. We could use alcGetIntegerv(), though.
- It's a little annoying to have something that only works with the NULL
device in alcGetIntegerv() ...but it's not a big deal, I guess.
- Is "changed" useful? We don't know if something was added or removed
without checking the list against a previous copy. If we're going to do
this, we should probably make it more useful than just telling you that
you need to reparse the device list.
- Do we report this to be true for each device that changes, or once for
each pile of changes between queries?
- Is this value true or false at startup?
- What happens if the app doesn't check this? Does it report true until
queried, and then resets to false? What happens if they request the
device list without checking this flag?
- I don't think this changes anything about when the AL does device
redetects. It may still have an event queue internally, or be checking
on another thread internally, or do it during the app's query.

This will need a new extension...all the things we're talking about can
coexist with ALC_EXT_disconnect, and won't need to rely on it, either.

One of these things we're talking about could be worked out, I think.

--ryan.


_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Stephen A. :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, 2009-09-18 at 16:41 -0700, Chris Robinson wrote:
> For languages with GC, I don't see why it wouldn't catch the references to the
> old strings being lost when a new set is allocated and given to the app,
> initiating a background cleanup of them.

The mere act of calling alcGetString causes an allocation & copy. There
is nothing to cache.

Yes, there are potential hacks around this issue, but do we really want
OpenAL to require hacks for efficient operation?

>
> FWIW, I don't think it's that bad of an idea to just retrieve the list every
> few seconds. If the cost of alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER) is
> too high, then can't you run it in a background thread? Something like: [...]

Not really. This would solve part of the issue (high cost of device
probing) but wouldn't solve the GC problem Please excuse me for pressing
this matter but this is quite important for devices like the iPhone,
where a garbage collection *will* cause visible stuttering.

Running alcGetIntegerv from a background thread would solve the problem
completely.

On Fri, 2009-09-18 at 21:37 -0400, Ryan C. Gordon wrote:
> I think if we're going to get a fight about transferring a string
> between C code and a managed language, there's going to be war about
> adding callbacks.

I recall callbacks being discussed for ALC_EXT_disconnect and I don't
think anyone raised any objections other than, "OpenAL resembles OpenGL
and OpenGL doesn't use callbacks." Callbacks shouldn't be a problem, as
long as (a) they are optional (i.e. you can specify null), (b) they are
used sparingly and only within ALC, and (c) they don't pass strings
directly. :-)

OpenCL is a great example of correct callback use. You can register
simple callbacks if you need extra information on context-, device- and
compiler-related matters, but you are not required to do so.

GLU is an example of what to avoid: its tessellation API is essentially
unusable from managed languages, as it relies on callbacks to pass
arrays of data. Works ok in C/C++ (where arrays are pointers), but
causes problems for everything else.

Here are my notes about this format...
>
>      alcGetBoolean(ALC_DEVICE_LIST_CHANGED, &trueOrFalse);
>
> - There's no alcGetBoolean. We could use alcGetIntegerv(), though.
> - It's a little annoying to have something that only works with the
> NULL
> device in alcGetIntegerv() ...but it's not a big deal, I guess.

Not really an issue.

> - Is "changed" useful? We don't know if something was added or
> removed
> without checking the list against a previous copy. If we're going to
> do
> this, we should probably make it more useful than just telling you
> that
> you need to reparse the device list.

Sounds useful and shouldn't be any harder to implement than a simple
true/false value. Something like the following maybe?

alcGetIntegerv:

    'data' - returns ALC_DEVICE_REMOVED, ALC_DEVICE_ADDED,
ALC_DEVICE_UNCHANGED when 'param' is ALC_DEVICE_LIST_CHANGED.

> - Do we report this to be true for each device that changes, or once
> for
> each pile of changes between queries?

Once only (the user is expected to re-parse the device list at this
point).

> - Is this value true or false at startup?
> - What happens if the app doesn't check this? Does it report true
> until
> queried, and then resets to false? What happens if they request the
> device list without checking this flag?

These are important questions. Possible solution: this query returns
true (or ALC_DEVICE_ADDED / ALC_DEVICE_REMOVED) until the user calls
alcGetString to retrieve the device list. At that point, it resets to
false / ALC_DEVICE_UNCHANGED until the device list is modified.

With this approach, the initial value should be true / ALC_DEVICE_ADDED,
which will be reset to false / ALC_DEVICE_UNCHANGED as soon as he
retrieves the device list.

> - I don't think this changes anything about when the AL does device
> redetects. It may still have an event queue internally, or be
> checking
> on another thread internally, or do it during the app's query.

> This will need a new extension...all the things we're talking about
can
> coexist with ALC_EXT_disconnect, and won't need to rely on it, either.

I think it's cleaner (and simpler to implement) this as a separate
extension. Maybe "ALC_EXT_device_notification"?

The important part is that the user be notified of device changes
without worrying about the implementation details (i.e.
alcGetIntegerv(ALC_DEVICE_LIST_CHANGED, ...) might  return a cached
value or it could cause a device probe - the user shouldn't have to
worry about this.)

Note: I don't think callbacks are necessary or useful for this
extension. In fact, they may be rather difficult to implement on
platforms that need probing (instead of device events).

_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Guilherme Balena Versiani :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello people,

Following the division of the problem, that seems we all agreed, I would
like to concentrate on the device listing only, and let the device
notification for another discussion.

We have two solutions until now:

    1) alcGetString always returns a "fresh" list of the available
devices, in a way opposite to the current Router behavior that is to
save a list in static memory and return the same list for every
subsequent call;
    2) The application must call ALC_EXT_disconnect to force the list to
be cleaned up.

I personally like the first option, as IMHO this is far more simple to
implement and adapt.

Let me create a metaphore of a real situation:

    1) Suppose you have an application, and in the moment you started
it, you didn't connect the soundcard device (for example an USB headset).
    2) You start some kind of transaction in the application that won't
persist if you restart the application (for example a tournament on a game).
    3) You connect an USB headset and now you want to use it in the
current running application.

How this could be solved (this is one solution, maybe you can have others):

    1) You open a configuration menu of the application and go to sound
configuration tab.
    2) In this moment, the application just calls alcGetString to create
the device list combo box and shows to the user.
    3) The user changes the device and the application calls
alcOpenDevice/alcCreateContext/alcMakeContextCurrent to change OpenAL
rendering device.

If the alcGetString function just resets the device listing for every
call, the application will start to work as expected.

Another case is when you disconnect the USB device. If this device was
selected by the OpenAL library, I think it is expected by the user that
the application stops to play sounds, and some kind of intervention
should be executed to adjust the sound playing again.

Regards,

-- Guilherme Balena Versiani.
_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Stephen A. :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Την Mon, 21 Sep 2009 20:20:27 +0300,ο(η) Guilherme Balena Versiani  
<guibv@...> έγραψε:

> Hello people,
>
> Following the division of the problem, that seems we all agreed, I would  
> like to concentrate on the device listing only, and let the device  
> notification for another discussion.
>
> We have two solutions until now:
>
>     1) alcGetString always returns a "fresh" list of the available  
> devices, in a way opposite to the current Router behavior that is to  
> save a list in static memory and return the same list for every  
> subsequent call;

This is what ALC_EXT_disconnect does. Read the spec here:  
http://icculus.org/alextreg/wiki/ALC_EXT_disconnect

>     2) The application must call ALC_EXT_disconnect to force the list to  
> be cleaned up.

You don't "call" ALC_EXT_disconnect. Your implementation either supports  
it or it doesn't. If this extension is supported, the behavior of  
alcGetString() and alcGetIntegerv is modified as per the extension spec.

_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Ryan C. Gordon-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> We have two solutions until now:
>
>     1) alcGetString always returns a "fresh" list of the available
> devices, in a way opposite to the current Router behavior that is to
> save a list in static memory and return the same list for every
> subsequent call;
>     2) The application must call ALC_EXT_disconnect to force the list to
> be cleaned up.

ALC_EXT_disconnect isn't a function, it's an extension name that, among
other things, specifies behaviour #1. So this is an easy solution.  :)

The router will need to be fixed to support ALC_EXT_disconnect, if it is
caching device names on behalf of the lower-level implementation.

> Another case is when you disconnect the USB device. If this device was
> selected by the OpenAL library, I think it is expected by the user that
> the application stops to play sounds, and some kind of intervention
> should be executed to adjust the sound playing again.

That's what ALC_EXT_disconnect is for: it specifies that this is what
happens.

   http://icculus.org/alextreg/wiki/ALC_EXT_disconnect

Basically, this use case is totally covered by this extension. The app
can poll for the specific device (without using alcGetString()) to see
if it was disconnected, to decide if they need to stop the game and ask
the user to pick a new device:

     ALint connected = 0;
     alcGetIntegerv(myDevice, ALC_CONNECTED, &connected);
     if (!connected) {
         alcCloseDevice(myDevice);
         ask_user_to_pick_a_new_device_or_whatever();
     }

No parsing of device lists required.

What we're talking about, really, is the opposite: how to know when new
hardware shows up (although it could be used to know when something
disconnected, too).

--ryan.

_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Guilherme Balena Versiani :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Do you know where can I find an implementation that supports ALC_EXT_disconnect? Is this extension multiplatform (I mean it is available)?

Can you explain me how the ALC_EXT_disconnect combines with OpenAL32.lib Router (Windows Router)? The problem I reported involves to change it, even if the OpenAL driver implementation supports ALC_EXT_disconnect...

Best regards,

-- Guilherme Balena Versiani.



2009/9/21 Ryan C. Gordon <icculus@...>

We have two solutions until now:

   1) alcGetString always returns a "fresh" list of the available devices, in a way opposite to the current Router behavior that is to save a list in static memory and return the same list for every subsequent call;
   2) The application must call ALC_EXT_disconnect to force the list to be cleaned up.

ALC_EXT_disconnect isn't a function, it's an extension name that, among other things, specifies behaviour #1. So this is an easy solution.  :)

The router will need to be fixed to support ALC_EXT_disconnect, if it is caching device names on behalf of the lower-level implementation.


Another case is when you disconnect the USB device. If this device was selected by the OpenAL library, I think it is expected by the user that the application stops to play sounds, and some kind of intervention should be executed to adjust the sound playing again.

That's what ALC_EXT_disconnect is for: it specifies that this is what happens. Basically, this use case is totally covered by this extension. The app can poll for the specific device (without using alcGetString()) to see if it was disconnected, to decide if they need to stop the game and ask the user to pick a new device:

   ALint connected = 0;
   alcGetIntegerv(myDevice, ALC_CONNECTED, &connected);
   if (!connected) {
       alcCloseDevice(myDevice);
       ask_user_to_pick_a_new_device_or_whatever();
   }

No parsing of device lists required.

What we're talking about, really, is the opposite: how to know when new hardware shows up (although it could be used to know when something disconnected, too).

--ryan.


_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel


_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Chris Robinson-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wednesday 23 September 2009 11:22:22 am Guilherme Balena Versiani wrote:
> Do you know where can I find an implementation that supports
> ALC_EXT_disconnect? Is this extension multiplatform (I mean it is
> available)?

The GIT version of OpenAL Soft does:
http://kcat.strangesoft.net/openal.html

The Windows backends don't really make use of it, though. I'm not sure how
DSound reports an opened device being irrecoverably lost, so I wouldn't know
what to watch for except errors that won't go away.. but I think that will get
false positives from devices that can't be shared and are just temporarily
taken by another process.

> Can you explain me how the ALC_EXT_disconnect combines with OpenAL32.lib
> Router (Windows Router)? The problem I reported involves to change it, even
> if the OpenAL driver implementation supports ALC_EXT_disconnect...

At its most fundamental level, it should work with the router. You open a
device as normal, pass the handle to alcGetIntegerv with ALC_CONNECTED, and
the router should pass it to the device's implementation which reports on the
device's status. Calling alcIsExtensionPresent with the opened device will
report if the extension is supported on that device.

For having the device strings change, the router will need to be modified to
requery the DLLs on behalf of the app. Dan said that could happen in the near
future. The individual drivers (wrap_oal.dll, ct_oal.dll, soft_oal.dll, etc)
will also need to support updating the device list when queried. The upcoming
1.9 release of OpenAL Soft will. Hopefully wrap_oal.dll (and ct_oal.dll as
needed) can do that soon, too.

FWIW, the router itself can't directly support ALC_EXT_disconnect. The
ALC_CONNECTED token only works on non-NULL device handles and the rest of the
behavior is specific to the given device (nothing the router explicitly
handles). The router just needs to not assume a static device list from the
drivers.
_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Guilherme Balena Versiani :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Chris Robinson wrote:
> The GIT version of OpenAL Soft does:
> http://kcat.strangesoft.net/openal.html
>  

That's fine. I will try to use it and make some tests.

> For having the device strings change, the router will need to be modified to
> requery the DLLs on behalf of the app. Dan said that could happen in the near
> future. The individual drivers (wrap_oal.dll, ct_oal.dll, soft_oal.dll, etc)
> will also need to support updating the device list when queried. The upcoming
> 1.9 release of OpenAL Soft will. Hopefully wrap_oal.dll (and ct_oal.dll as
> needed) can do that soon, too.
>  

Does soft_oal.dll built from GIT current support updating the device
list for every call to alcGetString? (Surely I will test, but if you
have any directions, it would be fine)

> FWIW, the router itself can't directly support ALC_EXT_disconnect. The
> ALC_CONNECTED token only works on non-NULL device handles and the rest of the
> behavior is specific to the given device (nothing the router explicitly
> handles). The router just needs to not assume a static device list from the
> drivers.
>  

That said, I will start to make changes to OpenAL Router for Windows (at
first place) to support this behavior. Could you tell me if there is
some new version of OpenAL Router other than the official repository at
Creative?

Regards,

-- Guilherme Balena Versiani.
_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

Re: ALC_ENUMERATE_ALL_EXT and pluggable sound devices

by Chris Robinson-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thursday 24 September 2009 10:16:12 am Guilherme Balena Versiani wrote:
> Does soft_oal.dll built from GIT current support updating the device
> list for every call to alcGetString? (Surely I will test, but if you
> have any directions, it would be fine)

Yes. It ultimately relies on DirectSound (for playback) and WinMM (for
capture) to actually enumerate new devices when queried, but AFAIK, they
should.

> > FWIW, the router itself can't directly support ALC_EXT_disconnect. The
> > ALC_CONNECTED token only works on non-NULL device handles and the rest of
> > the behavior is specific to the given device (nothing the router
> > explicitly handles). The router just needs to not assume a static device
> > list from the drivers.
>
> That said, I will start to make changes to OpenAL Router for Windows (at
> first place) to support this behavior. Could you tell me if there is
> some new version of OpenAL Router other than the official repository at
> Creative?

I'm not too sure if the router code on SVN is still up to date or not. I
*think* I read it was, or at least wasn't changed significantly, but that was
a while ago. I know the wrap_oal driver code isn't up-to-date.

If you're going to modify the router code on SVN, there's some things you need
to be very careful of. These things bit me pretty hard when I was implementing
it for OpenAL Soft.

First is (obviously) to make sure you don't leak the previous strings (change
the malloc calls to realloc, or free the old pointers first). Also be careful
that querying the default devices will also trigger rebuilding the list. You
can't have that happen, or else code like this:

const char *strlist = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
const char *strdef = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);

could leave strlist as an invalid pointer. Additionally, querying the device
list will change the default device, so this can fail, too:

const char *strdef = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
const char *strlist = alcGetString(NULL, ALC_DEVICE_SPECIFIER);

The way I handled this was to only build the list when the list was queried,
and find the default device from the existing list when that was queried (ie.
don't rebuild the whole list when the default device is requested, and don't
change the default device when the device list is requested).

As a consequence of this method, it should be encouraged to query the device
list first, before the default device name, or else the default device name
may be a disconnected device not found in the device list. I know some code
likes to query the default first, then the list.

One more point is, be careful to only rebuild the list being queried. Or else
this:

const char *pblist = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
const char *caplist = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);

can leave pblist as an invalid pointer due to the capture device list query
changing the playback device list.

Essentially, you need to break BuildDeviceList() into six functions..
BuildDeviceList - query the DLLs and build the playback device list
BuildCaptureDeviceList - query the DLLs and build the capture device list
BuildAllDevicesList - query the DLLs and build the all-devices list
FindDefaultDevice - find the default device in the playback device list
FindDefaultCaptureDevice - find the default device in the capture device list
FindDefaultAllDevices - find the default device in the all-devices list

Call the three Build* functions in DllMain under DLL_PROCESS_ATTACH (so an app
that queries the default device first has something to look in), and make sure
to call the appropriate one for the various alcGetString queries.
_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel
< Prev | 1 - 2 | Next >