SND_PCM_STATUS_CHANGE

"voice" currently switches automatically when a device is plugged in/out
without notification to the user.  There has been a change with BB10.2.x
that means that a device switch notification will be passed up to the
user in the form of a snd_pcm_plugin_write()/snd_pcm_plugin_read()
failure with a status of SND_PCM_STATUS_CHANGE if PLUGIN_ROUTING is
enabled, or a status of SND_PCM_STATUS_UNDERRUN/OVERRUN if it isn’t
(even if SND_PCM_STOP_ROLLOVER is in effect).

What this means is that clients of "voice" audio path should make sure
they explicitly handle these status events in their code; example code
is included below.  The recommended code modifications can be affected
immediately, they are backwards compatible with all previous versions of
BB10.

Example code:

int nRead;
char buffer[1024];  // actual buffer size is defined by client
configuration
size_t szBuffer = sizeof(buffer);
if ((nRead = snd_pcm_plugin_read(hPcm, (void*)buffer, szBuffer)) !=
szBuffer) {
int err;
snd_pcm_channel_status_t status;
memset(&status, 0, sizeof(status));
status.channel = SND_PCM_CHANNEL_CAPTURE;
if ((err = snd_pcm_plugin_status(hPcm, &status)) < 0) {
switch (status) {
case SND_PCM_STATUS_OVERRUN:    // Overrun (for capture only) - prepare
case SND_PCM_STATUS_UNDERRUN:   // Underrun (for playback only) -
prepare
case SND_PCM_STATUS_ERROR:      // HW error - prepare
case SND_PCM_STATUS_READY:      // Device ready - prepare
case SND_PCM_STATUS_CHANGE:     // Switching devices - prepare
if ((err = snd_pcm_plugin_prepare(hPcm, SND_PCM_CHANNEL_CAPTURE)) < 0) {
// printf("capture prepare failed - %s", snd_strerror(err));
// TODO handle error condition
} else {
// if SND_PCM_START_GO is used, then snd_pcm_plugin_go()
// needs to be called here as well. If this was for playback and
// SND_PCM_STOP_ROLLOVER was not being used, then snd_pcm_plugin_write()
// would need to be called before snd_pcm_plugin_go() to prime the
// playback frag queue.
}
break;
default:
// TODO handle other status conditions as per client needs
break;
}
} else {
// printf("capture status failed - %s", snd_strerror(err));
// TODO handle err as per client needs
}
}