static int playback(struct device_t *dv) { int r; struct alsa_t *alsa = (struct alsa_t*)dv->local; if (dv->player) { player_collect(dv->player, alsa->playback.buf, alsa->playback.period, alsa->playback.rate); } else { memset(alsa->playback.buf, 0, alsa->playback.period * DEVICE_CHANNELS * sizeof(short)); } r = snd_pcm_writei(alsa->playback.pcm, alsa->playback.buf, alsa->playback.period); if (r < 0) return r; if (r < alsa->playback.period) { fprintf(stderr, "alsa: playback underrun %d/%ld.\n", r, alsa->playback.period); } return 0; }
static void process_deck(struct device_t *dv, jack_nframes_t nframes) { int n; jack_default_audio_sample_t *in[DEVICE_CHANNELS], *out[DEVICE_CHANNELS]; jack_nframes_t remain; struct jack_t *jack = (struct jack_t*)dv->local; for (n = 0; n < DEVICE_CHANNELS; n++) { in[n] = jack_port_get_buffer(jack->input_port[n], nframes); assert(in[n] != NULL); out[n] = jack_port_get_buffer(jack->output_port[n], nframes); assert(out[n] != NULL); } /* For large values of nframes, communicate with the timecoder and * player in smaller blocks */ remain = nframes; while (remain > 0) { signed short buf[MAX_BLOCK * DEVICE_CHANNELS]; jack_nframes_t block; if (remain < MAX_BLOCK) block = remain; else block = MAX_BLOCK; /* Timecode input */ interleave(buf, in, block); if (dv->timecoder) timecoder_submit(dv->timecoder, buf, block); /* Audio output -- handle in the same loop for finer granularity */ player_collect(dv->player, buf, block, rate); uninterleave(out, buf, block); remain -= block; } }
void device_collect(struct device *dv, signed short *pcm, size_t n) { assert(dv->player != NULL); player_collect(dv->player, pcm, n); }