static gboolean try_write (Stream *stream) { #define STEP 1024 int avail, step, rendered, written, bpf; gboolean finish = FALSE; avail = swfdec_playback_stream_avail_update (stream); bpf = stream->par.bps * stream->par.pchan; while (avail > 0 && !finish) { gint16 data[2 * STEP]; step = MIN (avail, STEP); rendered = swfdec_audio_render (stream->audio, data, stream->offset, step); if (rendered < step) { finish = TRUE; } written = sio_write (stream->hdl, data, rendered * bpf) / bpf; avail -= written; stream->offset += rendered; stream->f_written += written; } if (finish) { swfdec_playback_stream_remove_handlers (stream); } return TRUE; #undef STEP }
static gboolean handle_stream (GIOChannel *source, GIOCondition cond, gpointer data) { Stream *stream = data; char *frag = malloc(stream->fragsize); if (frag == NULL) { g_printerr ("Failed to allocate fragment of size %d\n", stream->fragsize); return FALSE; } while (TRUE) { int ret; audio_buf_info spaceinfo; ret = ioctl(stream->dsp_fd, SNDCTL_DSP_GETOSPACE, &spaceinfo); if (ret == -1) { g_printerr ("Failed to get output buffer availability\n"); free(frag); return FALSE; } if (spaceinfo.fragments == 0) break; memset (frag, 0, stream->fragsize); swfdec_audio_render (stream->audio, (gint16 *)frag, stream->offset, stream->fragsize / SAMPLESIZE / CHANNELS); ret = write (stream->dsp_fd, frag, stream->fragsize); if (ret != stream->fragsize) { g_printerr ("Failed to write fragment\n"); free(frag); return FALSE; } stream->offset += stream->fragsize / SAMPLESIZE / CHANNELS; } free(frag); return TRUE; }
static void stream_write_callback (pa_stream *pa, size_t bytes, void *data) { Stream *stream = data; char *frag; unsigned int samples = bytes / SAMPLESIZE / CHANNELS; int err; if (stream->no_more) return; /* Adjust to our rounded-down number */ bytes = samples * SAMPLESIZE * CHANNELS; frag = g_try_malloc0 (bytes); if (frag == NULL) { g_printerr ("Failed to allocate fragment of size %d\n", (int)bytes); return; } /* Set up our fragment and render swfdec's audio into it. The swfdec audio * decoder renders deltas from the existing data in the fragment. */ swfdec_audio_render (stream->audio, (gint16 *)frag, stream->offset, samples); /* Send the new fragment out the PA stream */ err = pa_stream_write (pa, frag, bytes, NULL, 0, PA_SEEK_RELATIVE); if (err != 0) { g_printerr ("Failed to write fragment to PA stream: %s\n", pa_strerror(pa_context_errno(stream->sound->pa))); } /* Advance playback pointer */ stream->offset += samples; g_free (frag); }