Example #1
0
//-----------------------------------------------------------------------------
static void timer_set_period(uint16_t i)
{
  TC0->COUNT16.CC[0].reg = (F_CPU / 1000ul / 256) * i;
  timer_sync();

  TC0->COUNT16.COUNT.reg = 0;
  timer_sync();
}
Example #2
0
static size_t
httpd_output_play(void *data, const void *chunk, size_t size, GError **error)
{
	struct httpd_output *httpd = data;
	bool has_clients;

	g_mutex_lock(httpd->mutex);
	has_clients = httpd->clients != NULL;
	g_mutex_unlock(httpd->mutex);

	if (has_clients) {
		bool success;

		success = httpd_output_encode_and_play(httpd, chunk, size,
						       error);
		if (!success)
			return 0;
	}

	if (!httpd->timer->started)
		timer_start(httpd->timer);
	else
		timer_sync(httpd->timer);
	timer_add(httpd->timer, size);

	return size;
}
Example #3
0
//-----------------------------------------------------------------------------
static void timer_init(void)
{
  PM->APBCMASK.reg |= PM_APBCMASK_TC0;

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(TC0_GCLK_ID) |
      GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);

  TC0->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_MFRQ |
      TC_CTRLA_PRESCALER_DIV256 | TC_CTRLA_PRESCSYNC_RESYNC;
  timer_sync();

  TC0->COUNT16.COUNT.reg = 0;
  timer_sync();

  timer_set_period(PERIOD_SLOW);

  TC0->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
  timer_sync();

  TC0->COUNT16.INTENSET.reg = TC_INTENSET_MC(1);
  NVIC_EnableIRQ(TC0_IRQn);
}
static size_t
openal_play(void *data, const void *chunk, size_t size,
	    G_GNUC_UNUSED GError **error)
{
	struct openal_data *od = data;
	ALuint buffer;
	ALint num, state;

	if (alcGetCurrentContext() != od->context) {
		alcMakeContextCurrent(od->context);
	}

	alGetSourcei(od->source, AL_BUFFERS_PROCESSED, &num);

	if (od->filled < NUM_BUFFERS) {
		/* fill all buffers */
		buffer = od->buffers[od->filled];
		od->filled++;
	} else {
		/* wait for processed buffer */
		while (num < 1) {
			if (!od->timer->started) {
				timer_start(od->timer);
			} else {
				timer_sync(od->timer);
			}

			timer_add(od->timer, size);

			alGetSourcei(od->source, AL_BUFFERS_PROCESSED, &num);
		}

		alSourceUnqueueBuffers(od->source, 1, &buffer);
	}

	alBufferData(buffer, od->format, chunk, size, od->frequency);
	alSourceQueueBuffers(od->source, 1, &buffer);
	alGetSourcei(od->source, AL_SOURCE_STATE, &state);

	if (state != AL_PLAYING) {
		alSourcePlay(od->source);
	}

	return size;
}
static size_t
fifo_output_play(void *data, const void *chunk, size_t size,
		 GError **error)
{
	struct fifo_data *fd = (struct fifo_data *)data;
	ssize_t bytes;

	if (!fd->timer->started)
		timer_start(fd->timer);
	else
		timer_sync(fd->timer);

	timer_add(fd->timer, size);

	while (true) {
		bytes = write(fd->output, chunk, size);
		if (bytes > 0)
			return (size_t)bytes;

		if (bytes < 0) {
			switch (errno) {
			case EAGAIN:
				/* The pipe is full, so empty it */
				fifo_output_cancel(fd);
				continue;
			case EINTR:
				continue;
			}

			g_set_error(error, fifo_output_quark(), errno,
				    "Failed to write to FIFO %s: %s",
				    fd->path, g_strerror(errno));
			return 0;
		}
	}
}
Example #6
0
static void
fluidsynth_file_decode(struct decoder *decoder, const char *path_fs)
{
	static const struct audio_format audio_format = {
		.sample_rate = 48000,
		.bits = 16,
		.channels = 2,
	};
	char setting_sample_rate[] = "synth.sample-rate";
	/*
	char setting_verbose[] = "synth.verbose";
	char setting_yes[] = "yes";
	*/
	const char *soundfont_path;
	fluid_settings_t *settings;
	fluid_synth_t *synth;
	fluid_player_t *player;
	char *path_dup;
	int ret;
	Timer *timer;
	enum decoder_command cmd;

	soundfont_path =
		config_get_string("soundfont",
				  "/usr/share/sounds/sf2/FluidR3_GM.sf2");

	/* set up fluid settings */

	settings = new_fluid_settings();
	if (settings == NULL)
		return;

	fluid_settings_setnum(settings, setting_sample_rate, 48000);

	/*
	fluid_settings_setstr(settings, setting_verbose, setting_yes);
	*/

	/* create the fluid synth */

	synth = new_fluid_synth(settings);
	if (synth == NULL) {
		delete_fluid_settings(settings);
		return;
	}

	ret = fluid_synth_sfload(synth, soundfont_path, true);
	if (ret < 0) {
		g_warning("fluid_synth_sfload() failed");
		delete_fluid_synth(synth);
		delete_fluid_settings(settings);
		return;
	}

	/* create the fluid player */

	player = new_fluid_player(synth);
	if (player == NULL) {
		delete_fluid_synth(synth);
		delete_fluid_settings(settings);
		return;
	}

	/* temporarily duplicate the path_fs string, because
	   fluidsynth wants a writable string */
	path_dup = g_strdup(path_fs);
	ret = fluid_player_add(player, path_dup);
	g_free(path_dup);
	if (ret != 0) {
		g_warning("fluid_player_add() failed");
		delete_fluid_player(player);
		delete_fluid_synth(synth);
		delete_fluid_settings(settings);
		return;
	}

	/* start the player */

	ret = fluid_player_play(player);
	if (ret != 0) {
		g_warning("fluid_player_play() failed");
		delete_fluid_player(player);
		delete_fluid_synth(synth);
		delete_fluid_settings(settings);
		return;
	}

	/* set up a timer for synchronization; fluidsynth always
	   decodes in real time, which forces us to synchronize */
	/* XXX is there any way to switch off real-time decoding? */

	timer = timer_new(&audio_format);
	timer_start(timer);

	/* initialization complete - announce the audio format to the
	   MPD core */

	decoder_initialized(decoder, &audio_format, false, -1);

	do {
		int16_t buffer[2048];
		const unsigned max_frames = G_N_ELEMENTS(buffer) / 2;

		/* synchronize with the fluid player */

		timer_add(timer, sizeof(buffer));
		timer_sync(timer);

		/* read samples from fluidsynth and send them to the
		   MPD core */

		ret = fluid_synth_write_s16(synth, max_frames,
					    buffer, 0, 2,
					    buffer, 1, 2);
		/* XXX how do we see whether the player is done?  We
		   can't access the private attribute
		   player->status */
		if (ret != 0)
			break;

		cmd = decoder_data(decoder, NULL, buffer, sizeof(buffer),
				   0, 0, NULL);
	} while (cmd == DECODE_COMMAND_NONE);

	/* clean up */

	timer_free(timer);

	fluid_player_stop(player);
	fluid_player_join(player);

	delete_fluid_player(player);
	delete_fluid_synth(synth);
	delete_fluid_settings(settings);
}

static struct tag *
fluidsynth_tag_dup(const char *file)
{
	struct tag *tag = tag_new();

	/* to be implemented */
	(void)file;

	return tag;
}

static const char *const fluidsynth_suffixes[] = {
	"mid",
	NULL
};

const struct decoder_plugin fluidsynth_decoder_plugin = {
	.name = "fluidsynth",
	.init = fluidsynth_init,
	.file_decode = fluidsynth_file_decode,
	.tag_dup = fluidsynth_tag_dup,
	.suffixes = fluidsynth_suffixes,
};
Example #7
0
void game_step(Game* game) {
    cpSpaceStep(game->scene->space, game->timer->dt);
    timer_sync(game->timer);
}