blackberry/Core-Native-Community-Samples — pull request #20 by Gurtej (2013-10-16 14:47:57+00:00)
Title: 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
}
}