Ejemplo n.º 1
0
int xm_create_context(xm_context_t** ctxp, char* moddata, uint32_t rate) {
	int ret;
	size_t bytes_needed;
	char* mempool;
	xm_context_t* ctx;

	if((ret = xm_check_header_sanity(moddata))) {
		DEBUG("xm_check_header_sanity() returned %i", ret);
		return 1;
	}

	bytes_needed = xm_get_memory_needed_for_context(moddata);
	mempool = malloc(bytes_needed);
	if(mempool == NULL && bytes_needed > 0) {
		/* malloc() failed, trouble ahead */
		DEBUG("call to malloc() failed, returned %p", mempool);
		return 2;
	}

	/* Initialize most of the fields to 0, 0.f, NULL or false depending on type */
	memset(mempool, 0, bytes_needed);

	ctx = (*ctxp = (xm_context_t*)mempool);
	ctx->allocated_memory = mempool; /* Keep original pointer for free() */
	mempool += sizeof(xm_context_t);

	ctx->rate = rate;
	mempool = xm_load_module(ctx, moddata, mempool);

	ctx->channels = (xm_channel_context_t*)mempool;
	mempool += ctx->module.num_channels * sizeof(xm_channel_context_t);

	ctx->global_volume = 1.f;
	ctx->amplification = .5f; /* Purely empirical value */
	ctx->volume_ramp = (1.f / 128.f);
	ctx->panning_ramp = (1.f / 128.f);

	for(uint8_t i = 0; i < ctx->module.num_channels; ++i) {
		xm_channel_context_t* ch = ctx->channels + i;

		ch->ping = true;
		ch->vibrato_waveform = XM_SINE_WAVEFORM;
		ch->vibrato_waveform_retrigger = true;
		ch->tremolo_waveform = XM_SINE_WAVEFORM;
		ch->tremolo_waveform_retrigger = true;

		ch->volume = ch->volume_envelope_volume = ch->fadeout_volume = 1.0f;
		ch->panning = ch->panning_envelope_panning = .5f;
		ch->actual_volume = .0f;
		ch->actual_panning = .5f;
	}

	ctx->row_loop_count = (uint8_t*)mempool;
	mempool += MAX_NUM_ROWS * sizeof(uint8_t);

	return 0;
}
Ejemplo n.º 2
0
int xm_create_context_safe(xm_context_t** ctxp, const char* moddata, size_t moddata_length, uint32_t rate) {
#if XM_DEFENSIVE
	int ret;
#endif
	size_t bytes_needed;
	char* mempool;
	xm_context_t* ctx;

#if XM_DEFENSIVE
	if((ret = xm_check_sanity_preload(moddata, moddata_length))) {
		DEBUG("xm_check_sanity_preload() returned %i, module is not safe to load", ret);
		return 1;
	}
#endif

	bytes_needed = xm_get_memory_needed_for_context(moddata, moddata_length);
	mempool = malloc(bytes_needed);
	if(mempool == NULL && bytes_needed > 0) {
		/* malloc() failed, trouble ahead */
		DEBUG("call to malloc() failed, returned %p", (void*)mempool);
		return 2;
	}

	/* Initialize most of the fields to 0, 0.f, NULL or false depending on type */
	memset(mempool, 0, bytes_needed);

	ctx = (*ctxp = (xm_context_t*)mempool);
	ctx->allocated_memory = mempool; /* Keep original pointer for free() */
	mempool += sizeof(xm_context_t);

	ctx->rate = rate;
	mempool = xm_load_module(ctx, moddata, moddata_length, mempool);

	ctx->channels = (xm_channel_context_t*)mempool;
	mempool += ctx->module.num_channels * sizeof(xm_channel_context_t);

	ctx->global_volume = 1.f;
	ctx->amplification = .25f; /* XXX: some bad modules may still clip. Find out something better. */

#if XM_RAMPING
	ctx->volume_ramp = (1.f / 128.f);
	ctx->panning_ramp = (1.f / 128.f);
#endif

	for(uint8_t i = 0; i < ctx->module.num_channels; ++i) {
		xm_channel_context_t* ch = ctx->channels + i;

		ch->ping = true;
		ch->vibrato_waveform = XM_SINE_WAVEFORM;
		ch->vibrato_waveform_retrigger = true;
		ch->tremolo_waveform = XM_SINE_WAVEFORM;
		ch->tremolo_waveform_retrigger = true;

		ch->volume = ch->volume_envelope_volume = ch->fadeout_volume = 1.0f;
		ch->panning = ch->panning_envelope_panning = .5f;
		ch->actual_volume = .0f;
		ch->actual_panning = .5f;
	}

	ctx->row_loop_count = (uint8_t*)mempool;
	mempool += MAX_NUM_ROWS * sizeof(uint8_t);

#if XM_DEFENSIVE
	if((ret = xm_check_sanity_postload(ctx))) {
		DEBUG("xm_check_sanity_postload() returned %i, module is not safe to play", ret);
		xm_free_context(ctx);
		return 1;
	}
#endif

	return 0;
}