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

fixed the main player-logic a bit

git-svn-id: https://pimpmobile.svn.sourceforge.net/svnroot/pimpmobile/trunk@77 3d5ecaf0-f903-0410-b953-c2c1a4d75763
parent 7097de94
......@@ -7,7 +7,7 @@
#define CHANNELS 32
/* check the sample-rate calculator at http://www.pineight.com/gba/samplerates/ for more glitch-free samplerates */
#define SAMPLERATE (18157)
#define SAMPLERATE (18157 * 2)
/* only 130 bytes big, quite damn pleasing results */
#define AMIGA_DELTA_LUT_LOG_SIZE 7
......
......@@ -36,22 +36,6 @@ typedef struct
} pimp_sample_t;
typedef struct
{
s32 period;
s32 final_period; /* signed so we can check for underfow */
s32 porta_target;
u16 porta_speed;
s8 volume_slide_speed;
s8 volume;
u8 pan;
u8 note;
u8 effect;
u8 effect_param;
} pimp_channel_state_t;
typedef enum
{
EFF_NONE = 0x00,
......@@ -252,4 +236,24 @@ typedef struct
u8 channel_count;
} pimp_module_t;
typedef struct
{
s32 period;
s32 final_period; /* signed so we can check for underfow */
s32 porta_target;
u16 porta_speed;
s8 volume_slide_speed;
s8 volume;
u8 pan;
pimp_instrument_t *instrument;
pimp_sample_t *sample;
u8 note;
u8 effect;
u8 effect_param;
} pimp_channel_state_t;
#endif /* INTERNAL_H */
......@@ -39,9 +39,9 @@ unsigned get_linear_period(int note, int fine_tune)
assert(fine_tune >= -8);
assert(fine_tune < 8);
int xm_note = note - (12 * 1); // we extended our note-range with one octave.
int xm_note = note - (12 * 1) - 1; // we extended our note-range with one octave.
return 10 * 12 * 16 * 4 - xm_note * 16 * 4 - fine_tune / 2;
return (10 * 12 * 16 * 4 - xm_note * 16 * 4 - fine_tune / 2);
// return 10 * 12 * 16 * 4 - note * 16 * 4 - fine_tune / 2;
}
......
......@@ -152,7 +152,6 @@ static inline void mix_channel(channel_t &chan, s32 *target, size_t samples)
while (samples > 0 && detect_loop_event(chan, samples) == true)
{
DEBUG_COLOR(31, 31, 31);
do
{
assert((chan.sample_cursor >> 12) < chan.sample_length);
......@@ -176,18 +175,12 @@ static inline void mix_channel(channel_t &chan, s32 *target, size_t samples)
}
chan.sample_data = 0;
return;
}
}
DEBUG_COLOR(31, 0, 31);
timing_start();
assert(chan.sample_data != 0);
chan.sample_cursor = mix_samples(target, samples, chan.sample_data, chan.volume, chan.sample_cursor, chan.sample_cursor_delta);
timing_end();
DEBUG_COLOR(31, 0, 0);
}
void mixer::reset()
......@@ -206,8 +199,6 @@ void mixer::mix(s8 *target, size_t samples)
{
assert(samples > 0);
DEBUG_COLOR(0, 31, 31);
// zero out the sample-buffer
u32 zero = 0;
CpuFastSet(&zero, sound_mix_buffer, DMA_SRC_FIXED | (samples));
......@@ -219,7 +210,6 @@ void mixer::mix(s8 *target, size_t samples)
if (0 != chan.sample_data && 0 != chan.sample_cursor_delta) mix_channel(chan, sound_mix_buffer, samples);
}
dc_offs >>= 8;
DEBUG_COLOR(0, 31, 0);
register s32 *src = sound_mix_buffer;
register s8 *dst = target;
......@@ -264,5 +254,4 @@ void mixer::mix(s8 *target, size_t samples)
while (s--);
}
#undef ITERATION
DEBUG_COLOR(0, 0, 0);
}
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "mixer.h"
#include "debug.h"
#include <gba_base.h>
#include <gba_video.h>
int profile_counter = 0;
static u32 mix_simple(s32 *target, u32 samples, const u8 *sample_data, u32 vol, u32 sample_cursor, s32 sample_cursor_delta)
{
......@@ -10,7 +14,6 @@ static u32 mix_simple(s32 *target, u32 samples, const u8 *sample_data, u32 vol,
assert(sample_data != 0);
assert((samples & 7) == 0);
assert(samples != 0);
asm(
"\
b .Ldataskip%= \n\
......@@ -68,7 +71,6 @@ static u32 mix_simple(s32 *target, u32 samples, const u8 *sample_data, u32 vol,
[vol] "r"(vol)
: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "sp", "1", "2", "4", "cc"
);
return sample_cursor;
}
......@@ -150,7 +152,6 @@ static u32 mix_bresenham(s32 *target, u32 samples, const u8 *sample_data, u32 vo
[vol] "r"(vol)
: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "sp", "cc"
);
return ((sample_data - old_sample_data - 1) << 12) + (sample_cursor >> 20);
}
......@@ -173,12 +174,14 @@ u32 mixer::mix_samples(s32 *target, u32 samples, const u8 *sample_data, u32 vol,
// return mix_simple(target, samples, sample_data, vol, sample_cursor, sample_cursor_delta);
/* decide what innerloop to take */
if (sample_cursor_delta > 0 && sample_cursor_delta < u32((1 << 12) * 0.95))
if (sample_cursor_delta > 0 && sample_cursor_delta < (1 << 12))
{
return mix_bresenham(target, samples, sample_data, vol, sample_cursor, sample_cursor_delta);
u32 ret = mix_bresenham(target, samples, sample_data, vol, sample_cursor, sample_cursor_delta);
return ret;
}
else
{
return mix_simple(target, samples, sample_data, vol, sample_cursor, sample_cursor_delta);
u32 ret = mix_simple(target, samples, sample_data, vol, sample_cursor, sample_cursor_delta);
return ret;
}
}
......@@ -29,6 +29,12 @@
#include "math.h"
#include "debug.h"
#define PRINT_PATTERNS
static s8 sound_buffers[2][SOUND_BUFFER_SIZE] IWRAM_DATA;
static u32 sound_buffer_index = 0;
......@@ -41,6 +47,9 @@ static u32 curr_order = 0;
static u32 curr_bpm = 125;
static u32 curr_tempo = 5;
static u32 curr_tick = 0;
static s32 global_volume = 2 << 8; /* 24.8 fixed point */
static pimp_pattern_t *curr_pattern = 0;
static const unsigned char *pimp_sample_bank;
......@@ -85,6 +94,7 @@ static pimp_sample_t *get_sample(const pimp_module_t *mod, pimp_instrument_t *in
}
#ifdef PRINT_PATTERNS
void print_pattern_entry(const pimp_pattern_entry_t &pe)
{
if (pe.note != 0)
......@@ -98,6 +108,7 @@ void print_pattern_entry(const pimp_pattern_entry_t &pe)
}
else iprintf("--- ");
// iprintf("%02X ", pe.volume_command);
iprintf("%02X ", pe.effect_byte);
// iprintf("%02X %02X %X%02X\t", pe.instrument, pe.volume_command, pe.effect_byte, pe.effect_parameter);
}
......@@ -117,6 +128,7 @@ void print_pattern(const pimp_module_t *mod, pimp_pattern_t *pat)
iprintf("\n");
}
}
#endif
static pimp_callback callback = 0;
extern "C" void pimp_set_callback(pimp_callback in_callback)
......@@ -214,7 +226,9 @@ void update_row()
const pimp_pattern_entry_t *note = &get_pattern_data(mod, curr_pattern)[curr_row * mod->channel_count + c];
#ifdef PRINT_PATTERNS
print_pattern_entry(*note);
#endif
chan.effect = note->effect_byte;
chan.effect_param = note->effect_parameter;
......@@ -222,38 +236,40 @@ void update_row()
bool period_dirty = false;
bool volume_dirty = false;
// NOTE ON !
if (note->instrument > 0 && chan.effect != EFF_PORTA_NOTE)
if (note->instrument > 0)
{
pimp_instrument_t *instr = get_instrument(mod, note->instrument - 1);
pimp_sample_t *samp = get_sample(mod, instr, instr->sample_map[note->note]);
chan.instrument = get_instrument(mod, note->instrument - 1);
chan.sample = get_sample(mod, chan.instrument, chan.instrument->sample_map[note->note]);
chan.volume = chan.sample->volume;
volume_dirty = true;
}
if (chan.instrument != 0 && note->note > 0 && chan.effect != EFF_PORTA_NOTE)
{
chan.sample = get_sample(mod, chan.instrument, chan.instrument->sample_map[note->note]);
mc.sample_cursor = 0;
mc.sample_data = pimp_sample_bank + chan.sample->data_ptr;
mc.sample_length = chan.sample->length;
mc.loop_type = (mixer::loop_type_t)chan.sample->loop_type;
mc.loop_start = chan.sample->loop_start;
mc.loop_end = chan.sample->loop_start + chan.sample->loop_length;
int period;
if (mod->flags & FLAG_LINEAR_PERIODS)
{
period = get_linear_period(note->note, samp->fine_tune);
chan.period = get_linear_period(((s32)note->note) + chan.sample->rel_note, chan.sample->fine_tune);
}
else
{
period = get_amiga_period(note->note, samp->fine_tune);
chan.period = get_amiga_period(((s32)note->note) + chan.sample->rel_note, chan.sample->fine_tune);
}
chan.period = chan.final_period = period;
chan.final_period = chan.period;
period_dirty = true;
mc.sample_cursor = 0;
mc.sample_data = pimp_sample_bank + samp->data_ptr;
mc.sample_length = samp->length;
mc.loop_type = (mixer::loop_type_t)samp->loop_type;
mc.loop_start = samp->loop_start;
mc.loop_end = samp->loop_start + samp->loop_length;
}
if (note->instrument > 0)
{
pimp_instrument_t *instr = get_instrument(mod, note->instrument - 1);
pimp_sample_t *samp = get_sample(mod, instr, instr->sample_map[note->note]);
chan.volume = samp->volume;
chan.volume = chan.sample->volume;
volume_dirty = true;
}
......@@ -279,7 +295,8 @@ void update_row()
case EFF_PORTA_NOTE:
if (note->note > 0)
{
if (mod->flags & FLAG_LINEAR_PERIODS) chan.porta_target = get_linear_period(note->note, 0);
// no fine tune or relative note here, boooy
if (mod->flags & FLAG_LINEAR_PERIODS) chan.porta_target = get_linear_period(note->note + chan.sample->rel_note, 0);
else chan.porta_target = get_amiga_period(note->note, 0);
/* clamp porta-target period (should not be done for S3M) */
......@@ -340,8 +357,8 @@ void update_row()
chan.note = note->note;
break;
*/
default:
iprintf("eek E%X\n", chan.effect_param >> 4);
// default:
// iprintf("eek E%X\n", chan.effect_param >> 4);
}
break;
......@@ -370,8 +387,8 @@ void update_row()
case EFF_SET_BPM: break;
*/
default:
iprintf("eek %02X!\n", chan.effect);
// default:
// iprintf("eek %02X!\n", chan.effect);
// assert(0);
}
......@@ -389,11 +406,13 @@ void update_row()
if (volume_dirty)
{
mc.volume = chan.volume * 2;
mc.volume = (chan.volume * global_volume) >> 8;
}
}
#ifdef PRINT_PATTERNS
iprintf("\n");
#endif
curr_tick = 0;
curr_row++;
......@@ -509,7 +528,7 @@ static void update_tick()
if (volume_dirty)
{
mc.volume = chan.volume * 2;
mc.volume = (chan.volume * global_volume) >> 8;
}
}
curr_tick++;
......@@ -524,8 +543,6 @@ static void update_tick()
extern "C" void pimp_frame()
{
DEBUG_COLOR(31, 31, 31);
u32 samples_left = SOUND_BUFFER_SIZE;
s8 *buf = sound_buffers[sound_buffer_index];
......@@ -533,25 +550,18 @@ extern "C" void pimp_frame()
while (true)
{
int samples_to_mix = MIN(remainder, samples_left);
if (samples_to_mix != 0) mixer::mix(buf, samples_to_mix);
DEBUG_COLOR(31, 31, 31);
buf += samples_to_mix;
buf += samples_to_mix;
samples_left -= samples_to_mix;
remainder -= samples_to_mix;
if (!samples_left) break;
DEBUG_COLOR(0, 0, 0);
update_tick();
DEBUG_COLOR(31, 31, 31);
// printf("%d %d %d %d\n", mod->bpm, curr_row, curr_order, curr_tick);
// fixed point tick length
curr_tick_len += tick_len;
remainder = curr_tick_len >> 8;
curr_tick_len -= (curr_tick_len >> 8) << 8;
}
DEBUG_COLOR(0, 0, 0);
}
Supports Markdown
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