I'm implementing sync start as Takashi described... --------------- If the hardware supports the simultaneous triggering of multiple streams, add the sync support to the driver. Namely, - Add SNDRV_PCM_INFO_SYNC_START flag to PCM info field - Call snd_pcm_set_sync(substream) at each open callback - In the trigger callback, check all bundled streams via snd_pcm_group_for_each_entry(). Mark all the streams but the current one via snd_pcm_trigger_done(). Then start all streams at once. Ditto for stop and pause. -------------
Is there a simple way to test this with something like a mono sine wav file? A aplay mono.wav and then use and ALSA conf to copy the sine to all channels and then sync start them.
-----------
brutefit has this routine for sync start, does this look correct?
int bfio_synch_start(void) { snd_pcm_status_t *status; int err, n;
if (base_handle == NULL) { return 0; }
/* FIXME: the SND_PCM_STATE_RUNNING code would not be needed if the bfio_write autostart hack was not there */ snd_pcm_status_alloca(&status);
if (link_handles) { if ((err = snd_pcm_status(base_handle, status)) < 0) { fprintf(stderr, "ALSA I/O: Could not get status: %s.\n", snd_strerror(err)); return -1; } if (snd_pcm_status_get_state(status) == SND_PCM_STATE_RUNNING) { return 0; } if ((err = snd_pcm_start(base_handle)) < 0) { fprintf(stderr, "ALSA I/O: Could not start audio: %s.\n", snd_strerror(err)); return -1; } return 0; }
FOR_IN_AND_OUT { for (n = 0; n < n_handles[IO]; n++) { if ((err = snd_pcm_status(handles[IO][n], status)) < 0) { fprintf(stderr, "ALSA I/O: Could not get status: %s.\n", snd_strerror(err)); return -1; } if (snd_pcm_status_get_state(status) == SND_PCM_STATE_RUNNING) { continue; }
if ((err = snd_pcm_start(handles[IO][n])) < 0) { fprintf(stderr, "ALSA I/O: Could not start audio: %s.\n", snd_strerror(err)); return -1; } } } return 0; }