Skip to content
Browse files

Merge pull request #14 from jhoffmannrim/master

Fix PlayWav to listen for Audio Device events
  • Loading branch information...
2 parents add7366 + 4839043 commit dbdc977b6941f8a983815ea8f5f9418ff6e0449d @jhoffmannrim jhoffmannrim committed Mar 16, 2012
Showing with 312 additions and 224 deletions.
  1. +312 −224 PlayWav/main.c
View
536 PlayWav/main.c
@@ -33,6 +33,7 @@
#include <bps/bps.h>
#include <bps/audiomixer.h>
+#include <bps/audiodevice.h>
#include <bps/dialog.h>
#include <bps/navigator.h>
@@ -46,7 +47,11 @@ static char msg[MSG_SIZE];
const char *riff_id = "RIFF";
const char *wave_id = "WAVE";
-#define WAV_RELATIVE_PATH "/app/native/sample.wav"
+#define WAV_RELATIVE_PATH "app/native/sample.wav"
+
+#define SUCCESS 0
+#define FAILURE -1
+
typedef struct
{
@@ -74,201 +79,136 @@ typedef struct
}
wave_hdr;
+int card = -1;
+
+snd_pcm_t *pcm_handle;
+snd_pcm_info_t info;
+snd_pcm_channel_params_t pp;
+snd_pcm_channel_setup_t setup;
+snd_pcm_channel_info_t pi;
+
+snd_mixer_t *mixer_handle;
+snd_mixer_group_t group;
+
+wave_hdr wav_header;
+int sample_rate;
+int sample_channels;
+int sample_bits;
+
int
-err (char *message)
+err(char *message)
{
- snprintf (msg, MSG_SIZE, "%s\n%s", message, strerror(errno));
+ snprintf(msg, MSG_SIZE, "%s\n%s", message, strerror(errno));
show_dialog_message(msg);
return -1;
}
int
-find_tag (FILE * fp, const char *tag)
+find_tag(FILE * fp, const char *tag)
{
- int ret_val = 0;
+ int ret_val = 0;
riff_tag tag_bfr = { "", 0 };
- // Keep reading until we find the tag or hit the EOF.
- while (fread ((unsigned char *) &tag_bfr, sizeof (tag_bfr), 1, fp))
- {
+ /* Keep reading until we find the tag or hit the EOF. */
+ while (fread((unsigned char *) &tag_bfr, sizeof(tag_bfr), 1, fp)) {
- // If this is our tag, set the length and break.
- if (strncmp (tag, tag_bfr.tag, sizeof tag_bfr.tag) == 0)
- {
- ret_val = ENDIAN_LE32 (tag_bfr.length);
+ /* If this is our tag, set the length and break. */
+ if (strncmp(tag, tag_bfr.tag, sizeof tag_bfr.tag) == 0) {
+ ret_val = ENDIAN_LE32(tag_bfr.length);
break;
}
- // Skip ahead the specified number of bytes in the stream
- fseek (fp, tag_bfr.length, SEEK_CUR);
+ /* Skip ahead the specified number of bytes in the stream */
+ fseek(fp, tag_bfr.length, SEEK_CUR);
}
- // Return the result of our operation
+ /* Return the result of our operation */
return (ret_val);
}
int
-check_hdr (FILE * fp)
+check_hdr(FILE * fp)
{
riff_hdr riff_header = { "", 0 };
- // Read the header and, if successful, play the file
- // file or WAVE file.
- if (fread ((unsigned char *) &riff_header, sizeof (riff_hdr), 1, fp) == 0)
+ /* Read the header and make sure that this is indeed a Wave file. */
+ if (fread((unsigned char *) &riff_header, sizeof(riff_hdr), 1, fp) == 0)
return 0;
- if (strncmp (riff_header.Riff, riff_id, strlen (riff_id)) ||
- strncmp (riff_header.Wave, wave_id, strlen (wave_id)))
+ if (strncmp(riff_header.Riff, riff_id, strlen(riff_id)) ||
+ strncmp(riff_header.Wave, wave_id, strlen(wave_id)))
return -1;
return 0;
}
+/*
+ * General setup of the libasound audio mixer and pcm components.
+ * Some of the settings are based on the format of the wav data.
+ */
int
-main (int argc, char **argv)
+setup_snd(const char * name)
{
- int card = -1;
- int dev = 0;
- snd_pcm_t *pcm_handle;
- FILE *file;
- wave_hdr wav_header;
- int samples;
- int sample_rate;
- int sample_channels;
- int sample_bits;
- char *sample_buffer;
- int fragsize = -1;
-
- int rtn;
- int final_return_code = -1;
- snd_pcm_channel_info_t pi;
- snd_mixer_t *mixer_handle;
- snd_mixer_group_t group;
- snd_pcm_channel_params_t pp;
- snd_pcm_channel_setup_t setup;
- int bsize, bytes_read, total_written = 0;
- fd_set rfds, wfds;
- uint32_t voice_mask[] = { 0, 0, 0, 0 };
- snd_pcm_voice_conversion_t voice_conversion;
- int voice_override = 0;
- int num_frags = -1;
- char input_file[PATH_MAX];
- char cwd[PATH_MAX];
- int exit_application = 0;
-
- /*
- * Before we can listen for events from the BlackBerry Tablet OS platform
- * services, we need to initialize the BPS infrastructure
- */
- bps_initialize();
-
- if (setup_screen() != EXIT_SUCCESS) {
- printf("Unable to set up the screen. Exiting.");
- return 0;
+ int fragsize = -1;
+ int num_frags = -1;
+ int rtn;
+ char *dev_name;
+
+ if (NULL == name) {
+ dev_name = "pcmPreferred";
+ } else {
+ dev_name = (char *) name;
}
- /*
- * Once the BPS infrastructure has been initialized we can register for
- * events from the various BlackBerry Tablet OS platform services. The
- * Navigator service manages and delivers application life cycle and
- * visibility events.
- * For this sample, we request Navigator events so we can track when
- * the system is terminating the application (NAVIGATOR_EXIT event). This allows
- * us to clean up application resources.
- */
- if (BPS_SUCCESS != navigator_request_events(0)) {
- fprintf(stderr, "Error requesting navigator events: %s", strerror(errno));
- exit(-1);
- }
-
- if (BPS_SUCCESS != dialog_request_events(0)) {
- fprintf(stderr, "Error requesting dialog events: %s", strerror(errno));
- exit(-1);
- }
- /*
- * Create and display the dialog.
- */
- create_dialog();
-
- if ((rtn = snd_pcm_open_preferred (&pcm_handle, &card, &dev, SND_PCM_OPEN_PLAYBACK)) < 0)
- {
- err ("device open");
- goto fail3;
- }
-
- getcwd(cwd, PATH_MAX);
- rtn = snprintf(input_file, PATH_MAX, "%s%s", cwd, WAV_RELATIVE_PATH);
- if (rtn > PATH_MAX - 1)
- {
- err ("File name and path too long");
- goto fail4;
- }
-
- if ((file = fopen (input_file, "r")) == 0)
- {
- err ("File open failed");
- goto fail4;
+ if ((rtn = snd_pcm_open_name(&pcm_handle, dev_name, SND_PCM_OPEN_PLAYBACK)) < 0) {
+ snprintf(msg, MSG_SIZE, "snd_pcm_open_name failed: %s\n", snd_strerror(rtn));
+ show_dialog_message(msg);
+ return FAILURE;
}
- if (check_hdr (file) == -1)
- {
- err ("check_hdr failed");
- goto fail5;
+ if ((rtn = snd_pcm_info(pcm_handle, &info)) < 0) {
+ snprintf(msg, MSG_SIZE, "snd_pcm_info failed: %s\n", snd_strerror(rtn));
+ goto setup_failure;
}
-
- samples = find_tag (file, "fmt ");
- fread (&wav_header, sizeof (wav_header), 1, file);
- fseek (file, (samples - sizeof (wave_hdr)), SEEK_CUR);
-
- sample_rate = ENDIAN_LE32 (wav_header.samples_per_sec);
- sample_channels = ENDIAN_LE16 (wav_header.channels);
- sample_bits = ENDIAN_LE16 (wav_header.bits_per_sample);
-
- snprintf(msg, MSG_SIZE, "SampleRate = %d, channels = %d, SampleBits = %d\n", sample_rate, sample_channels,
- sample_bits);
- show_dialog_message(msg);
+ card = info.card;
/* disabling mmap is not actually required in this example but it is included to
* demonstrate how it is used when it is required.
*/
- if ((rtn = snd_pcm_plugin_set_disable (pcm_handle, PLUGIN_DISABLE_MMAP)) < 0)
- {
- snprintf(msg, MSG_SIZE, "snd_pcm_plugin_set_disable failed: %s\n", snd_strerror (rtn));
- show_dialog_message(msg);
- goto fail5;
+ if ((rtn = snd_pcm_plugin_set_disable(pcm_handle, PLUGIN_DISABLE_MMAP)) < 0) {
+ snprintf(msg, MSG_SIZE, "snd_pcm_plugin_set_disable failed: %s\n", snd_strerror(rtn));
+ goto setup_failure;
}
- memset (&pi, 0, sizeof (pi));
+ memset(&pi, 0, sizeof(pi));
pi.channel = SND_PCM_CHANNEL_PLAYBACK;
- if ((rtn = snd_pcm_plugin_info (pcm_handle, &pi)) < 0)
- {
- snprintf(msg, MSG_SIZE, "snd_pcm_plugin_info failed: %s\n", snd_strerror (rtn));
- show_dialog_message(msg);
- goto fail5;
+ if ((rtn = snd_pcm_plugin_info(pcm_handle, &pi)) < 0) {
+ snprintf(msg, MSG_SIZE, "snd_pcm_plugin_info failed: %s\n", snd_strerror(rtn));
+ goto setup_failure;
}
- memset (&pp, 0, sizeof (pp));
+ memset(&pp, 0, sizeof(pp));
pp.mode = SND_PCM_MODE_BLOCK;
pp.channel = SND_PCM_CHANNEL_PLAYBACK;
pp.start_mode = SND_PCM_START_FULL;
pp.stop_mode = SND_PCM_STOP_STOP;
pp.buf.block.frag_size = pi.max_fragment_size;
- if (fragsize != -1)
- {
+ if (fragsize != -1) {
pp.buf.block.frag_size = fragsize;
}
+
pp.buf.block.frags_max = num_frags;
pp.buf.block.frags_min = 1;
pp.format.interleave = 1;
pp.format.rate = sample_rate;
pp.format.voices = sample_channels;
- if (ENDIAN_LE16 (wav_header.format_tag) == 6)
+ if (ENDIAN_LE16(wav_header.format_tag) == 6)
pp.format.format = SND_PCM_SFMT_A_LAW;
- else if (ENDIAN_LE16 (wav_header.format_tag) == 7)
+ else if (ENDIAN_LE16(wav_header.format_tag) == 7)
pp.format.format = SND_PCM_SFMT_MU_LAW;
else if (sample_bits == 8)
pp.format.format = SND_PCM_SFMT_U8;
@@ -277,145 +217,293 @@ main (int argc, char **argv)
else
pp.format.format = SND_PCM_SFMT_S16_LE;
- strcpy (pp.sw_mixer_subchn_name, "Wave playback channel");
- if ((rtn = snd_pcm_plugin_params (pcm_handle, &pp)) < 0)
- {
- snprintf(msg, MSG_SIZE, "snd_pcm_plugin_params failed: %s\n", snd_strerror (rtn));
- show_dialog_message(msg);
- goto fail5;
- }
-
- if ((rtn = snd_pcm_plugin_prepare (pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {
- snprintf(msg, MSG_SIZE, "snd_pcm_plugin_prepare failed: %s\n", snd_strerror (rtn));
- show_dialog_message(msg);
- goto fail5;
+ strcpy(pp.sw_mixer_subchn_name, "Wave playback channel");
+ if ((rtn = snd_pcm_plugin_params(pcm_handle, &pp)) < 0) {
+ snprintf(msg, MSG_SIZE, "snd_pcm_plugin_params failed: %s\n", snd_strerror(rtn));
+ goto setup_failure;
}
- if (voice_override)
- {
- snd_pcm_plugin_get_voice_conversion (pcm_handle, SND_PCM_CHANNEL_PLAYBACK,
- &voice_conversion);
- voice_conversion.matrix[0] = voice_mask[0];
- voice_conversion.matrix[1] = voice_mask[1];
- voice_conversion.matrix[2] = voice_mask[2];
- voice_conversion.matrix[3] = voice_mask[3];
- snd_pcm_plugin_set_voice_conversion (pcm_handle, SND_PCM_CHANNEL_PLAYBACK,
- &voice_conversion);
+ if ((rtn = snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {
+ snprintf(msg, MSG_SIZE, "snd_pcm_plugin_prepare failed: %s\n", snd_strerror(rtn));
+ goto setup_failure;
}
- memset (&setup, 0, sizeof (setup));
- memset (&group, 0, sizeof (group));
+ memset(&setup, 0, sizeof(setup));
+ memset(&group, 0, sizeof(group));
setup.channel = SND_PCM_CHANNEL_PLAYBACK;
setup.mixer_gid = &group.gid;
- if ((rtn = snd_pcm_plugin_setup (pcm_handle, &setup)) < 0)
- {
- snprintf(msg, MSG_SIZE, "snd_pcm_plugin_setup failed: %s\n", snd_strerror (rtn));
- show_dialog_message(msg);
- goto fail5;
+ if ((rtn = snd_pcm_plugin_setup(pcm_handle, &setup)) < 0) {
+ snprintf(msg, MSG_SIZE, "snd_pcm_plugin_setup failed: %s\n", snd_strerror(rtn));
+ goto setup_failure;
}
- if (group.gid.name[0] == 0)
- {
+ if (group.gid.name[0] == 0) {
snprintf(msg, MSG_SIZE, "Mixer Pcm Group [%s] Not Set \n", group.gid.name);
- show_dialog_message(msg);
- goto fail5;
+ goto setup_failure;
}
- if ((rtn = snd_mixer_open (&mixer_handle, card, setup.mixer_device)) < 0)
- {
- snprintf(msg, MSG_SIZE, "snd_mixer_open failed: %s\n", snd_strerror (rtn));
- show_dialog_message(msg);
- goto fail5;
+ if ((rtn = snd_mixer_open(&mixer_handle, card, setup.mixer_device)) < 0) {
+ snprintf(msg, MSG_SIZE, "snd_mixer_open failed: %s\n", snd_strerror(rtn));
+ goto setup_failure;
}
char tmp[MSG_SIZE];
- snprintf (msg, MSG_SIZE, "Format %s \n", snd_pcm_get_format_name (setup.format.format));
- snprintf (tmp, MSG_SIZE, "Frag Size %d \n", setup.buf.block.frag_size);
+ snprintf(msg, MSG_SIZE, "Format %s \n", snd_pcm_get_format_name(setup.format.format));
+ snprintf(tmp, MSG_SIZE, "Frag Size %d \n", setup.buf.block.frag_size);
strlcat(msg, tmp, MSG_SIZE);
- snprintf (tmp, MSG_SIZE, "Total Frags %d \n", setup.buf.block.frags);
+ snprintf(tmp, MSG_SIZE, "Total Frags %d \n", setup.buf.block.frags);
strlcat(msg, tmp, MSG_SIZE);
- snprintf (tmp, MSG_SIZE, "Rate %d \n", setup.format.rate);
+ snprintf(tmp, MSG_SIZE, "Rate %d \n", setup.format.rate);
strlcat(msg, tmp, MSG_SIZE);
- snprintf (tmp, MSG_SIZE, "Voices %d \n", setup.format.voices);
+ snprintf(tmp, MSG_SIZE, "Voices %d \n", setup.format.voices);
strlcat(msg, tmp, MSG_SIZE);
- snprintf (tmp, MSG_SIZE, "Mixer Pcm Group [%s]\n", group.gid.name);
+ snprintf(tmp, MSG_SIZE, "Mixer Pcm Group [%s]\n", group.gid.name);
strlcat(msg, tmp, MSG_SIZE);
show_dialog_message(msg);
+ return SUCCESS;
+
+setup_failure:
+ show_dialog_message(msg);
+ snd_pcm_close(pcm_handle);
+ return FAILURE;
+}
+
+int
+main(int argc, char **argv)
+{
+ FILE *file;
+ int samples;
+ char *sample_buffer;
+
+ int rtn, final_return_code = -1, exit_application = 0;
+
+ int bsize, bytes_read, total_written = 0;
+ fd_set rfds, wfds;
+ char input_file[PATH_MAX];
+ char cwd[PATH_MAX];
+
+
+ /*
+ * Before we can listen for events from the BlackBerry Tablet OS platform
+ * services, we need to initialize the BPS infrastructure
+ */
+ bps_initialize();
+
+ if (setup_screen() != EXIT_SUCCESS) {
+ printf("Unable to set up the screen. Exiting.");
+ exit(-1);
+ }
+
+ /*
+ * Once the BPS infrastructure has been initialized we can register for
+ * events from the various BlackBerry Tablet OS platform services. The
+ * Navigator service manages and delivers application life cycle and
+ * visibility events.
+ *
+ * For this sample, we request Navigator events so we can track when
+ * the system is terminating the application (NAVIGATOR_EXIT event).
+ * This allows us to clean up application resources.
+ *
+ * We request Audio Device events because we want to make sure that
+ * we properly handle changes in audio output.
+ *
+ * We request dialog events to properly initialize the dialog
+ * subsystem in order to display status and error messages.
+ */
+ if (BPS_SUCCESS != navigator_request_events(0)) {
+ fprintf(stderr, "Error requesting navigator events: %s", strerror(errno));
+ exit(-1);
+ }
+
+ if (BPS_SUCCESS != dialog_request_events(0)) {
+ fprintf(stderr, "Error requesting dialog events: %s", strerror(errno));
+ exit(-1);
+ }
+
+ if (BPS_SUCCESS != audiodevice_request_events(0)) {
+ fprintf(stderr, "Error requesting audio device events: %s", strerror(errno));
+ exit(-1);
+ }
+
+ /*
+ * Create and display the dialog.
+ */
+ create_dialog();
+
+ /*
+ * Open and check the input file.
+ */
+ getcwd(cwd, PATH_MAX);
+ rtn = snprintf(input_file, PATH_MAX, "%s/%s", cwd, WAV_RELATIVE_PATH);
+ if (rtn > PATH_MAX - 1) {
+ err("File name and path too long");
+ goto fail1;
+ }
+
+ if ((file = fopen(input_file, "r")) == 0) {
+ err("File open failed");
+ goto fail1;
+ }
+
+ if (check_hdr(file) == -1) {
+ err("check_hdr failed");
+ goto fail2;
+ }
+
+ /*
+ * Parse the headers in the wav file to figure out what kind of data we
+ * are dealing with in the file.
+ */
+ samples = find_tag(file, "fmt ");
+ fread(&wav_header, sizeof(wav_header), 1, file);
+ fseek(file,(samples - sizeof(wave_hdr)), SEEK_CUR);
+
+ sample_rate = ENDIAN_LE32(wav_header.samples_per_sec);
+ sample_channels = ENDIAN_LE16(wav_header.channels);
+ sample_bits = ENDIAN_LE16(wav_header.bits_per_sample);
+
+ snprintf(msg, MSG_SIZE, "SampleRate = %d, channels = %d, SampleBits = %d\n", sample_rate, sample_channels,
+ sample_bits);
+ show_dialog_message(msg);
+
+ if (setup_snd(NULL)) {
+ goto fail2;
+ }
+
bsize = setup.buf.block.frag_size;
- samples = find_tag (file, "data");
- sample_buffer = malloc (bsize);
- FD_ZERO (&rfds);
- FD_ZERO (&wfds);
+ samples = find_tag(file, "data");
+ sample_buffer = malloc(bsize);
+ if (!sample_buffer) {
+ goto fail3;
+ }
+
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
bytes_read = 1;
- while (total_written < samples && bytes_read > 0)
- {
- if (tcgetpgrp (0) == getpid ())
- FD_SET (STDIN_FILENO, &rfds);
- FD_SET (snd_mixer_file_descriptor (mixer_handle), &rfds);
- FD_SET (snd_pcm_file_descriptor (pcm_handle, SND_PCM_CHANNEL_PLAYBACK), &wfds);
-
- rtn = max (snd_mixer_file_descriptor (mixer_handle),
- snd_pcm_file_descriptor (pcm_handle, SND_PCM_CHANNEL_PLAYBACK));
-
- if (select (rtn + 1, &rfds, &wfds, NULL, NULL) == -1)
- {
- err ("select");
- goto fail6;
+ while (total_written < samples && bytes_read > 0 ) {
+ bps_event_t *event = NULL;
+
+ while (BPS_SUCCESS == bps_get_event(&event, 0) && event) {
+ /*
+ * If it is a NAVIGATOR_EXIT event then we are done so stop
+ * processing events, clean up and exit
+ */
+ if (bps_event_get_domain(event) == navigator_get_domain()) {
+ if (NAVIGATOR_EXIT == bps_event_get_code(event)) {
+ exit_application = 1;
+ goto success;
+ }
+ }
+
+ if (bps_event_get_domain(event) == audiodevice_get_domain()) {
+ /*
+ * If it is a audio device event then it means a new audio device
+ * has been enabled and a switch is required. We close the old,
+ * open the new audio device using the path and get the card number so
+ * that we can close and re-open the mixer with the new card
+ * number.
+ */
+
+ const char * audiodevice_path = audiodevice_event_get_path(event);
+
+ if (NULL == audiodevice_path) {
+ snprintf(msg, MSG_SIZE, "audiodevice_event_get_path failed: %s\n", snd_strerror(rtn));
+ show_dialog_message(msg);
+ goto fail5;
+ }
+
+ if ((rtn = snd_mixer_close(mixer_handle)) < 0) {
+ snprintf(msg, MSG_SIZE, "snd_mixer_close failed: %s\n", snd_strerror(rtn));
+ show_dialog_message(msg);
+ goto fail4;
+ }
+
+ if ((rtn = snd_pcm_close(pcm_handle)) < 0) {
+ snprintf(msg, MSG_SIZE, "snd_pcm_close failed: %s\n", snd_strerror(rtn));
+ show_dialog_message(msg);
+ goto fail3;
+ }
+
+ if (setup_snd(audiodevice_path)) {
+ /*
+ * setup_snd() closes pcm and mixer handles in the case of error so we
+ * skip clean up of the handles in the case of failure.
+ */
+ goto fail3;
+ }
+ }
+ }
+
+ if (tcgetpgrp(0) == getpid())
+ FD_SET(STDIN_FILENO, &rfds);
+ FD_SET(snd_mixer_file_descriptor(mixer_handle), &rfds);
+ FD_SET(snd_pcm_file_descriptor(pcm_handle, SND_PCM_CHANNEL_PLAYBACK), &wfds);
+
+ rtn = max(snd_mixer_file_descriptor(mixer_handle),
+ snd_pcm_file_descriptor(pcm_handle, SND_PCM_CHANNEL_PLAYBACK));
+
+ if (select(rtn + 1, &rfds, &wfds, NULL, NULL) == -1) {
+ err("select");
+ goto fail5;
}
- if (FD_ISSET (snd_pcm_file_descriptor (pcm_handle, SND_PCM_CHANNEL_PLAYBACK), &wfds))
- {
+ if (FD_ISSET(snd_pcm_file_descriptor(pcm_handle, SND_PCM_CHANNEL_PLAYBACK), &wfds)) {
snd_pcm_channel_status_t status;
- int written = 0;
+ int written = 0;
- if ((bytes_read = fread (sample_buffer, 1, min (samples - total_written, bsize), file)) <= 0)
+ if ((bytes_read = fread(sample_buffer, 1, min(samples - total_written, bsize), file)) <= 0)
continue;
- written = snd_pcm_plugin_write (pcm_handle, sample_buffer, bytes_read);
- if (written < bytes_read)
- {
- memset (&status, 0, sizeof (status));
+ written = snd_pcm_plugin_write(pcm_handle, sample_buffer, bytes_read);
+ if (written < bytes_read) {
+ memset(&status, 0, sizeof(status));
status.channel = SND_PCM_CHANNEL_PLAYBACK;
- if (snd_pcm_plugin_status (pcm_handle, &status) < 0)
- {
+ if (snd_pcm_plugin_status(pcm_handle, &status) < 0) {
show_dialog_message("underrun: playback channel status error\n");
- goto fail6;
+ goto fail5;
}
if (status.status == SND_PCM_STATUS_READY ||
- status.status == SND_PCM_STATUS_UNDERRUN)
- {
- if (snd_pcm_plugin_prepare (pcm_handle, SND_PCM_CHANNEL_PLAYBACK) < 0)
- {
+ status.status == SND_PCM_STATUS_UNDERRUN) {
+ if (snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK) < 0) {
show_dialog_message("underrun: playback channel prepare error\n");
- goto fail6;
+ goto fail5;
}
}
if (written < 0)
written = 0;
- written += snd_pcm_plugin_write (pcm_handle, sample_buffer + written, bytes_read - written);
+ written += snd_pcm_plugin_write(pcm_handle, sample_buffer + written, bytes_read - written);
}
total_written += written;
}
}
- bytes_read = snd_pcm_plugin_flush (pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
+success:
+ bytes_read = snd_pcm_plugin_flush(pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
final_return_code = 0;
-
-fail6:
- rtn = snd_mixer_close (mixer_handle);
+ /*
+ * there are return codes to these close calls, but we would do the same
+ * thing regardless of error or success so we do not check the return codes.
+ */
fail5:
- fclose (file);
+ snd_mixer_close(mixer_handle);
fail4:
- rtn = snd_pcm_close (pcm_handle);
+ snd_pcm_close(pcm_handle);
fail3:
+ free(sample_buffer);
+ sample_buffer = NULL;
+fail2:
+ fclose(file);
+fail1:
+
- /*
- * Process Navigator events until we receive a NAVIGATOR_EXIT event.
- */
while (!exit_application) {
/*
+ * Something went wrong so there is probably an error message and
+ * we don't want to exit right away because we want the user to see
+ * the message in the dialog.
+ *
* Using a negative timeout (-1) in the call to bps_get_event(...)
* ensures that we don't busy wait by blocking until an event is
* available.
@@ -425,9 +513,8 @@ main (int argc, char **argv)
if (event) {
/*
- * If it is a NAVIGATOR_EXIT event then set the exit_application
- * flag so the application will stop processing events, clean up
- * and exit
+ * If it is a NAVIGATOR_EXIT event then we are done so stop
+ * processing events, clean up and exit
*/
if (bps_event_get_domain(event) == navigator_get_domain()) {
if (NAVIGATOR_EXIT == bps_event_get_code(event)) {
@@ -436,6 +523,7 @@ main (int argc, char **argv)
}
}
}
+
/*
* Destroy the dialog, if it exists and cleanup screen resources.
*/

0 comments on commit dbdc977

Please sign in to comment.
Something went wrong with that request. Please try again.