PCM events

PCM events are sent when changes occur to a subchannel.

There many situations where it's useful to notify an application when an event occurs to the subchannel so that the application can take appropriate actions. For example, an application may maintain its own states, and so needs to update its application-specific states.

PCM events are generated when changes occur to the subchannel. This can be a state change or when the subchannel has been muted by the system. It's important to note that PCM events aren't generated when API calls are made; for example, a call to snd_pcm_*_pause() won't generate an event. As an example, events are when audio management moves a subchannel from the RUNNING state to the SUSPENDED state.

By default, applications won't receive events unless they call the snd_pcm_set_filter() to register to receive them. To register for events, a bitmask must be applied to the enable member in the snd_pcm_filter_t argument to the snd_pcm_set_filter() as shown here:

 /* Enable PCM events */
snd_pcm_filter_t pevent;
pevent.enable = ( (1<<SND_PCM_EVENT_AUDIOMGMT_STATUS) |
                  (1<<SND_PCM_EVENT_AUDIOMGMT_MUTE) |
                  (1<<SND_PCM_EVENT_OUTPUTCLASS) );
snd_pcm_set_filter(pcm_handle, SND_PCM_CHANNEL_PLAYBACK, &pevent);

You can use snd_pcm_get_filter() to see which events you registered for.

To work with the PCM events, call snd_pcm_channel_read_event(). That call is a non-blocking call where you can then use select() (with exceptfds) or call poll() (with POLLRDBAND) to retrieve the PCM events from your queue. For information about those functions, see the QNX Neutrino C Library Reference.

When you retrieve an event, use the snd_pcm_event_t structure to determine the event type you received. You can use the data member (a union) to get event data. These are the available event types:

SND_PCM_EVENT_AUDIOMGMT_STATUS
This event type indicates that an audio management related state change occurred. The data member of the event contains the previous state (old_status) and new state (new_status). Here are valid state changes that cause an event to be generated:
  • From RUNNING (SND_PCM_STATUS_RUNNING) to SUSPENDED (SND_PCM_STATUS_SUSPENDED) or PAUSED (SND_PCM_STATUS_PAUSED)
  • From SUSPENDED to RUNNING or PAUSED
  • From PAUSED to SUSPENDED
If forced ducking is enabled and the subchannel isn't actively streaming, here are the state changes that cause an event to be generated:
  • From PREPARED (SND_PCM_STATUS_PREPARED) to SUSPENDED (SND_PCM_STATUS_SUSPENDED)
  • From SUSPENDED (SND_PCM_STATUS_SUSPENDED) to PREPARED (SND_PCM_STATUS_PREPARED)
  • From SUSPENDED (SND_PCM_STATUS_SUSPENDED) to READY (SND_PCM_STATUS_READY)
SND_PCM_EVENT_AUDIOMGMT_MUTE
Mute events occur for audio types that have their volume ducked to zero due to audio management policies being applied on the system. Though the volume is zero, it's still in the RUNNING state. If preemption is configured, being ducked to zero won't generate this event, instead an SND_PCM_EVENT_AUDIOMGMT_STATUS event is generated.
SND_PCM_EVENT_OUTPUTCLASS
The event indicates a change to the output class of the PCM playback device. You can use the old_output_class and new_output_class members in the snd_pcm_outputclass_event_t member to get the information about the previous output class and current output class, respectively.