Commit a8849f59 authored by Erik Faye-Lund's avatar Erik Faye-Lund
Browse files

make samplerate adjustable


Signed-off-by: default avatarErik Faye-Lund <kusmabite@gmail.com>
parent 496bf0ff
......@@ -42,7 +42,7 @@ OBJS = \
libgbfs.o \
gbfs_stdio.o
MODULES = $(shell find data -iname *.xm)
MODULES = $(shell find data -iname *.xm -or -iname *.mod)
BIN_MODULES = $(MODULES:=.bin)
......
......@@ -11,7 +11,7 @@
/* check the sample-rate calculator at http://www.pineight.com/gba/samplerates/ for more glitch-free samplerates */
/* 0x4000100 = 0xFFFF, 0x4000102 = 0x0083 */
#define PIMP_SAMPLERATE (18157.16)
#define PIMP_GBA_SAMPLERATE (18157.16)
/* #define PIMP_SAMPLERATE (31536.12) */
/* enable / disable assert */
......
......@@ -61,7 +61,7 @@ static struct pimp_mod_context pimp_gba_ctx EWRAM_DATA;
/* setup some constants */
#define CYCLES_PR_FRAME 280896
#define CYCLES_PR_SAMPLE ((int)((1 << 24) / ((float)PIMP_SAMPLERATE)))
#define CYCLES_PR_SAMPLE ((int)((1 << 24) / ((float)PIMP_GBA_SAMPLERATE)))
#define SOUND_BUFFER_SIZE ((int)((float)CYCLES_PR_FRAME / CYCLES_PR_SAMPLE))
/* mix and playback-buffers */
......@@ -73,7 +73,7 @@ void pimp_gba_init(const struct pimp_module *module, const void *sample_bank)
{
u32 zero = 0;
pimp_gba_mixer.mix_buffer = pimp_gba_mix_buffer;
pimp_mod_context_init(&pimp_gba_ctx, (const pimp_module*)module, (const u8*)sample_bank, &pimp_gba_mixer);
pimp_mod_context_init(&pimp_gba_ctx, (const pimp_module*)module, (const u8*)sample_bank, &pimp_gba_mixer, PIMP_GBA_SAMPLERATE);
CpuFastSet(&zero, &pimp_gba_sound_buffers[0][0], DMA_SRC_FIXED | ((SOUND_BUFFER_SIZE / 4) * 2));
REG_SOUNDCNT_H = SNDA_VOL_100 | SNDA_L_ENABLE | SNDA_R_ENABLE | SNDA_RESET_FIFO;
......
......@@ -44,17 +44,15 @@ unsigned pimp_get_linear_period(int note, int fine_tune)
}
#include "linear_delta_lut.h"
unsigned pimp_get_linear_delta(unsigned period)
unsigned pimp_get_linear_delta(unsigned int period, unsigned int delta_scale)
{
const unsigned int scale = (unsigned int)((1.0 / (PIMP_SAMPLERATE)) * (1 << 3) * (1ULL << 32));
unsigned p = (12 * 16 * 4 * 14) - period;
unsigned octave = p / (12 * 16 * 4);
unsigned octave_period = p % (12 * 16 * 4);
unsigned delta = linear_delta_lut[octave_period] << octave;
/* BEHOLD: the expression of the devil (this compiles to one arm-instruction) */
delta = ((long long)delta * scale + (1ULL << 31)) >> 32;
delta = ((long long)delta * (delta_scale >> 3) + (1ULL << 31)) >> 32;
return delta;
}
#endif /* NO_LINEAR_PERIODS */
......@@ -92,10 +90,8 @@ unsigned pimp_get_amiga_period(int note, int fine_tune)
#include "amiga_delta_lut.h"
#define AMIGA_DELTA_LUT_SIZE (1 << AMIGA_DELTA_LUT_LOG2_SIZE)
#define AMIGA_DELTA_LUT_FRAC_BITS (15 - AMIGA_DELTA_LUT_LOG2_SIZE)
unsigned pimp_get_amiga_delta(unsigned period)
unsigned pimp_get_amiga_delta(unsigned int period, unsigned int delta_scale)
{
const unsigned int scale = (unsigned int)(((1.0 / (PIMP_SAMPLERATE)) * (1 << 6)) * (1LL << 32));
int d1, d2;
unsigned int delta;
unsigned int shamt = clz16(period) - 1;
......@@ -112,7 +108,7 @@ unsigned pimp_get_amiga_delta(unsigned period)
else delta >>= AMIGA_DELTA_LUT_FRAC_BITS - shamt;
/* BEHOLD: the expression of the devil 2.0 (this compiles to one arm-instruction) */
delta = ((long long)delta * scale + (1ULL << 31)) >> 32;
delta = ((long long)delta * delta_scale + (1ULL << 31)) >> 32;
return delta;
}
#endif /* NO_AMIGA_PERIODS */
......@@ -48,12 +48,12 @@ static INLINE unsigned clz8(unsigned input)
#ifndef NO_LINEAR_PERIODS
unsigned pimp_get_linear_delta(unsigned period);
unsigned pimp_get_linear_delta(unsigned int period, unsigned int delta_scale);
unsigned pimp_get_linear_period(int note, int fine_tune);
#endif
#ifndef NO_AMIGA_PERIODS
unsigned pimp_get_amiga_delta(unsigned period);
unsigned pimp_get_amiga_delta(unsigned period, unsigned int delta_scale);
unsigned pimp_get_amiga_period(int note, int fine_tune);
#endif
......
......@@ -5,7 +5,7 @@
#include "pimp_mod_context.h"
void pimp_mod_context_init(struct pimp_mod_context *ctx, const pimp_module *mod, const u8 *sample_bank, struct pimp_mixer *mixer)
void pimp_mod_context_init(struct pimp_mod_context *ctx, const pimp_module *mod, const u8 *sample_bank, struct pimp_mixer *mixer, const float samplerate)
{
int i;
ASSERT(ctx != NULL);
......@@ -13,6 +13,7 @@ void pimp_mod_context_init(struct pimp_mod_context *ctx, const pimp_module *mod,
ctx->mod = mod;
ctx->sample_bank = sample_bank;
ctx->mixer = mixer;
pimp_mod_context_set_samplerate(ctx, samplerate);
/* setup default player-state */
ctx->tick_len = 0;
......@@ -69,6 +70,12 @@ void pimp_mod_context_init(struct pimp_mod_context *ctx, const pimp_module *mod,
pimp_mixer_reset(ctx->mixer);
}
void pimp_mod_context_set_samplerate(struct pimp_mod_context *ctx, const float samplerate)
{
ctx->samplerate = samplerate;
ctx->delta_scale = (unsigned int)((1.0 / samplerate) * (1 << 6) * (1ULL << 32));
}
/* "hard" jump in a module */
void pimp_mod_context_set_pos(struct pimp_mod_context *ctx, int row, int order)
{
......@@ -142,7 +149,7 @@ void pimp_mod_context_set_next_pos(struct pimp_mod_context *ctx, int row, int or
void pimp_mod_context_set_bpm(struct pimp_mod_context *ctx, int bpm)
{
/* we're using 8 fractional-bits for the tick-length */
const int temp = (int)(((PIMP_SAMPLERATE) * 5) * (1 << 8));
const int temp = (int)((ctx->samplerate * 5) * (1 << 8));
ASSERT(ctx != NULL);
ASSERT(bpm > 0);
......
......@@ -44,10 +44,15 @@ struct pimp_mod_context
const pimp_module *mod;
struct pimp_mixer *mixer;
float samplerate;
unsigned int delta_scale;
pimp_callback callback;
};
void pimp_mod_context_init(struct pimp_mod_context *ctx, const pimp_module *mod, const u8 *sample_bank, struct pimp_mixer *mixer);
void pimp_mod_context_init(struct pimp_mod_context *ctx, const pimp_module *mod, const u8 *sample_bank, struct pimp_mixer *mixer, const float samplerate);
void pimp_mod_context_set_samplerate(struct pimp_mod_context *ctx, const float samplerate);
void pimp_mod_context_set_bpm(struct pimp_mod_context *ctx, int bpm);
void pimp_mod_context_set_tempo(struct pimp_mod_context *ctx, int tempo);
......
......@@ -454,11 +454,11 @@ static void pimp_mod_context_update_row(struct pimp_mod_context *ctx)
{
if (ctx->mod->flags & FLAG_LINEAR_PERIODS)
{
mc->sample_cursor_delta = pimp_get_linear_delta(chan->final_period);
mc->sample_cursor_delta = pimp_get_linear_delta(chan->final_period, ctx->delta_scale);
}
else
{
mc->sample_cursor_delta = pimp_get_amiga_delta(chan->final_period);
mc->sample_cursor_delta = pimp_get_amiga_delta(chan->final_period, ctx->delta_scale);
}
}
......@@ -625,11 +625,11 @@ static void pimp_mod_context_update_tick(struct pimp_mod_context *ctx)
{
if (ctx->mod->flags & FLAG_LINEAR_PERIODS)
{
mc->sample_cursor_delta = pimp_get_linear_delta(chan->final_period);
mc->sample_cursor_delta = pimp_get_linear_delta(chan->final_period, ctx->delta_scale);
}
else
{
mc->sample_cursor_delta = pimp_get_amiga_delta(chan->final_period);
mc->sample_cursor_delta = pimp_get_amiga_delta(chan->final_period, ctx->delta_scale);
}
}
......
......@@ -51,7 +51,4 @@ dump_render$(EXE_EXT): toplevel/dump_render.c $(TEST_DEPS_SOURCES)
$(LINK.cpp) $^$(LOADLIBES) $(LDLIBS) -o $@
%.wav : %.sb
sox -r 18157 $< $@
%.wav : %.ub
sox -r 18157 $< $@
sox -r 44100 $< $@
\ No newline at end of file
#include "../../src/pimp_mod_context.h"
#include "../../src/pimp_sample_bank.h"
#include "../../src/pimp_render.h"
#include "../../converter/load_module.h"
#include "../../src/load_module.h"
#include <stdio.h>
#include <stdlib.h>
......@@ -57,7 +57,7 @@ int main(int argc, char *argv[])
/* setup rendering */
mixer.mix_buffer = mixbuf;
pimp_mod_context_init(&ctx, mod, (const u8*)sample_bank.data, &mixer);
pimp_mod_context_init(&ctx, mod, (const u8*)sample_bank.data, &mixer, 44100.0f);
/* render module to buffer */
pimp_render(&ctx, buf, SAMPLES);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment