Author Topic: BASS_Init on other devices than default (-1) blocks other apps on the system  (Read 1663 times)

chris_djbench

  • Posts: 19
Hey folks, I'm coming up with another problem.

In this case I think it may be useful to mention I am using ubuntu 10.04 and my default audio device is hda intel.

Ok here it comes:

When initializing at the beginning using the BASS_Init function with -1, which tells BASS to use the default output, other apps on the system are not effected by my application. That means further, that, when I have e.g. a media player opened, i still can start my app and get sound output.

When I now set a certain device in the BASS_Init call, e.g. device 1 (which is my default device, since i just have one built in soundcard), and I have a media player running or the browser and a youtube site is opened, I get BASS_ERR_AVAIL messages in my app, that the device is not available.

Why is that?! Is the init call on a certain device blocking?! How can I call it none blocking? Or is there any other solution for this problem? =)

Thanks,
chris

EDIT: here is some code that shows the two different ways of initializing a device. the first is the default (-1) and in the for loop its the initializing of a certain device. the first way doesn't block other apps, the second does.

Code: [Select]
  //Default Device initialisieren
  //if (!BASS_Init(-1, 44100, BASS_DEVICE_LATENCY, 0, NULL))
    //ERRCHECK("bass_init");


  //!DebugAusgabe der verfügbaren Geräte
  int a, count = 0;
  BASS_DEVICEINFO info;

  //Schleife ab 2, dadurch wird das default device (1) ausgelassen
  for (a=2; BASS_GetDeviceInfo(a, &info); a++)
      if (info.flags&BASS_DEVICE_ENABLED) // device is enabled
      {
        //printf("Device %d: %s\n", a, info.name);
        count++; // count it

        //in den Vektor mit verfügbaren Devices eintragen
        m_vecDevices.push_back(info.name);

        //jedes Device gleich mal initialisieren
        //a = device number
        //frequency
        //flags
        //window
        //clsid
        if (!BASS_Init(a, 44100, BASS_DEVICE_LATENCY, 0, NULL))
          ERRCHECK("bass_init");
      }
  //printf("----------\ntotal number of devices: %d\n\n", count);
« Last Edit: 8 Nov '10 - 06:23 by chris_djbench »

Ionut Cristea

  • Posts: 1545
  Can you check without BASS_DEVICE_LATENCY flag?

 Several weeks ago..i've made something like this and working fine :)

Ian @ un4seen

  • Administrator
  • Posts: 20437
In this case I think it may be useful to mention I am using ubuntu 10.04...

Device initialization is a bit different in the Linux version compared to the others. Firstly, there is a "Default" device hardcoded to device number 1, which uses the default output set in the ALSA config (that could map directly to one of the other devices or it could use ALSA plugins). The real devices start at number 2, and they are initialized for exclusive access by default, hence other apps may not be able to use them at the same time. A BASS_DEVICE_DMIX flag option is available, which initializes the device using the ALSA "dmix" plugin to allow other apps to share the device (if they use "dmix" too). You can find more info on this in the Linux thread.

I'm not really sure whether the device initialization should default to using "dmix" (there are pros and cons mentioned in the other thread). That decision is what's holding up the official release (on the BASS webpage) of the Linux version; suggestions are welcome :)

chris_djbench

  • Posts: 19
Hey there,

the use of the BASS_DEVICE_DMIX flag results in the following message:
ALSA lib pcm_dmix.c:1010:(snd_pcm_dmix_open) unable to open slave
and the same BASS_ERROR_NOTAVAIL like before.

Does the message mean, there is a problem with my local alsa configuration or is it a problem related to BASS?

And the change to not take BASS_DEVICE_LATENCY did not have any effect either. Still blocking the others or returning error messages if others are running before...

Ian @ un4seen

  • Administrator
  • Posts: 20437
That looks like something else is already using the device. Are you able to initialize the same device without the DMIX flag immediately after/before it failed with the flag?

Is the "Default" device (number 1) working? You should probably default to using that device if a sound server (eg. PulseAudio) is being used, to have the BASS output go through that. You could have an option in your app to let the user choose another device if they want.

chris_djbench

  • Posts: 19
If no other app that uses sound output is running, then I am able to initialize the device either with the DMIX flag or without. Both works.
But if some other app that uses sound output is running I am not able to initialize the device neither with DMIX flag nor without. Both things don't work.


Right now I'm not quite sure if the default device (called by "1") was working but, as far as I remember, that gave an error too. I will check that later that day again.


We are already providing the chance to let the user choose the preferred output. Or better: we provide the chance to let the user choose which outputs are used for what. Because we need all of them (two in our case).
The problem is, that every device you want to use, needs to be initialized before. And so we come to the beginning of our problem. Cause we need to initialize all outputs, which blocks everything.

Is there another way to assign different outputs when having multiple soundcards, then initializing every device and switch internally by BASS_SetDevice()?

Ian @ un4seen

  • Administrator
  • Posts: 20437
If no other app that uses sound output is running, then I am able to initialize the device either with the DMIX flag or without. Both works.
But if some other app that uses sound output is running I am not able to initialize the device neither with DMIX flag nor without. Both things don't work.

OK, that makes sense. It would have been strange if you were able to initialize the device without the DMIX flag but not with it :)

It looks to me like a sound server is being used; I think Ubuntu uses PulseAudio by default? As I say, using the "Default" device (device number 1) should send BASS's output through that. If you use that device, are you then able to use output with other apps too?

We are already providing the chance to let the user choose the preferred output. Or better: we provide the chance to let the user choose which outputs are used for what. Because we need all of them (two in our case).
The problem is, that every device you want to use, needs to be initialized before. And so we come to the beginning of our problem. Cause we need to initialize all outputs, which blocks everything.

Is there another way to assign different outputs when having multiple soundcards, then initializing every device and switch internally by BASS_SetDevice()?

I don't see how that can be avoided; if you want to use a device, it needs to be initialized.

If you want maximum flexibility (eg. specific output formats and lowest latency), then you will probably want to initialize the devices for exclusive access, ie. not the "Default" device or DMIX. If you would also like to let other apps use the devices when you're not, you could just initialize them prior to playback and free them when playback ends. You would need to recreate the output streams when doing that (they are freed along with their device), but you can avoid that for any source/decoding channels by creating them on the "no sound" device (number 0).