Example #1
0
static void *
alsa_thread(void *arg)
{
	gint16 *ptr;
	int err, cptr;
	guint8 *buf;
	sfx_pcm_device_t *self = (sfx_pcm_device_t *) arg;

	buf = (guint8 *) malloc(period_size * frame_size);

	while (run_thread) {
		ptr = (gint16 *) buf;
		cptr = period_size;

		sci_gettime(&last_callback_secs, &last_callback_usecs);

		self->timer->block();

		if (alsa_sfx_timer_callback)
			alsa_sfx_timer_callback(alsa_sfx_timer_data);

		self->timer->unblock();

		sfx_audbuf_read(&audio_buffer, buf, period_size);

		while (cptr > 0) {
			err = snd_pcm_writei(handle, ptr, cptr);
			if (err == -EAGAIN)
				continue;
			if (err < 0) {
				if (xrun_recovery(handle, err) < 0) {
					fprintf(stderr, "[SND:ALSA] Write error: %s\n", snd_strerror(err));
					run_thread = 0;
				}
				break;  /* skip one period */
			}
			ptr += err * channels;
			cptr -= err;
		}
	}

	free(buf);
	return NULL;
}
Example #2
0
static void
timer_sdl_internal_callback(void *userdata, byte *dest, int len)
{
	sci_gettime(&last_callback_secs, &last_callback_usecs);
	last_callback_len = len;

	if (sdl_sfx_timer_callback)
		sdl_sfx_timer_callback(sdl_sfx_timer_data);

#if 0
	if (!sfx_audbuf_read_timestamp(&audio_buffer, &ts)) {
		int delta = (buf_size - len) / frame_size;
		sfx_timestamp_t real_ts;
		long deltatime;
		long sec2, usec2;
		sci_gettime(&sec2, &usec2);

		real_ts = sfx_timestamp_add(sfx_new_timestamp(sec, usec, rate), delta);

		deltatime = sfx_timestamp_usecs_diff(ts, real_ts);

		fprintf(stderr, "[SDL] Frames requested: %d  Playing %ld too late. Needed %ldus for computations.\n",
				len / frame_size, deltatime,
			(usec2-usec) + (sec2-sec)*1000000);

		if (abs(deltatime) > DELTA_TIME_LIMIT)
			sciprintf("[SND:SDL] Very high delta time for PCM playback: %ld too late (%d frames in the future)\n",
				  deltatime, sfx_timestamp_frame_diff(sfx_new_timestamp(sec, usec, rate), ts));

#if 0
		if (deltatime < 0) {
			/* Read and discard frames, explicitly underrunning */
			int max_read = len / frame_size;
			int frames_to_kill = sfx_timestamp_frame_diff(real_ts, ts);

			while (frames_to_kill) {
				int d = frames_to_kill > max_read? max_read : frames_to_kill;
				sfx_audbuf_read(&audio_buffer, dest, d);
				frames_to_kill -= d;
			}
		}
#endif
	}
#endif
	sfx_audbuf_read(&audio_buffer, dest, len / frame_size);

#if 0
	if (!fil) {
		fil = fopen("/tmp/sdl.log", "w");
	}
	{
		int i;
		int end = len / frame_size;
		gint16 *d = dest;
		fprintf(fil, "Writing %d/%d\n", len, frame_size);
		for (i = 0; i < end; i++) {
			fprintf(fil, "\t%d\t%d\n", d[0], d[1]);
			d += 2;
		}
	}
#endif
}