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

added pseudo-working porta up and down.

git-svn-id: https://pimpmobile.svn.sourceforge.net/svnroot/pimpmobile/trunk@53 3d5ecaf0-f903-0410-b953-c2c1a4d75763
parent 92d6f963
......@@ -39,6 +39,7 @@ endif
LIBS = $(LIBGBA)/lib/libgba.a
OBJS = \
src/pimpmobile.o \
src/math.iwram.o \
src/mixer.iwram.o \
src/mixer_arm.iwram.o
......
......@@ -97,12 +97,58 @@ void convert_samples(module_t *mod)
}
}
/*
x pad byte
b byte ( 8 bit)
h short (16 bit)
i int (32 bit)
*/
#include <stdarg.h>
void print_datastruct(const char *format, ...)
{
va_list marker;
va_start(marker, format);
unsigned int data;
while (*format != '\0')
{
switch (*format++)
{
case 'x':
printf("x");
break;
case 'b':
data = va_arg(marker, int);
printf("%i", data);
break;
case 'h':
data = va_arg(marker, int);
printf("%i", data);
break;
case 'i':
data = va_arg(marker, int);
printf("%i", data);
break;
}
}
va_end(marker);
}
module_t *load_module_xm(FILE *fp);
module_t *load_module_mod(FILE *fp);
module_t *load_module_s3m(FILE *fp);
int main(int argc, char *argv[])
{
print_datastruct("xixIx", -5, -5);
exit(0);
if (argc < 2) print_usage();
for (int i = 1; i < argc; ++i)
......
......@@ -8,6 +8,7 @@
#include "../include/pimpmobile.h"
#include "../src/mixer.h"
#include "../src/config.h"
extern const u8 sample[];
extern const u8 sample_end[];
......@@ -60,6 +61,8 @@ int main()
mixer::channels[0].sample_cursor_delta = 1 << 12;
mixer::channels[0].volume = 255;
mixer::channels[0].sample = &mixer_sample;
iprintf("%i\n", SOUND_BUFFER_SIZE);
/*
mixer::channels[1].sample_cursor = 0;
......
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <math.h>
#include <typeinfo>
#include "src/config.h" // get the current config
#include "src/math.h" // get the current config
/*
this is the lut-generator for pimpmobile.
the delta-luts are dependant on the sample-rate, and must be re-generated whenever the sample-rate-config has changed.
*/
const unsigned char clz_lut[256] =
{
0x8, 0x7, 0x6, 0x6, 0x5, 0x5, 0x5, 0x5, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};
static inline unsigned clz(unsigned input)
{
/* 2 iterations of binary search */
unsigned c = 0;
if (input & 0xFFFF0000) input >>= 16;
else c = 16;
if (input & 0xFF00) input >>= 8;
else c += 8;
/* a 256 entries lut ain't too bad... */
return clz_lut[input] + c;
}
static inline unsigned clz16(unsigned input)
{
/* 1 iteration of binary search */
unsigned c = 0;
if (input & 0xFF00) input >>= 8;
else c += 8;
/* a 256 entries lut ain't too bad... */
return clz_lut[input] + c;
}
unsigned short linear_freq_lut[12 * 64];
unsigned get_linear_delta(unsigned period)
{
unsigned p = (12 * 64 * 14) - period;
unsigned octave = p / (12 * 64);
unsigned octave_period = p % (12 * 64);
unsigned frequency = linear_freq_lut[octave_period] << octave;
// BEHOLD: the expression of the devil 2.0
frequency = ((long long)frequency * unsigned((1.0 / SAMPLERATE) * (1 << 3) * (1ULL << 32)) + (1ULL << 31)) >> 32;
return frequency;
}
#define AMIGA_FREQ_TABLE_LOG_SIZE 7
#define AMIGA_FREQ_TABLE_SIZE (1 << AMIGA_FREQ_TABLE_LOG_SIZE)
#define AMIGA_FREQ_TABLE_FRAC_BITS (15 - AMIGA_FREQ_TABLE_LOG_SIZE)
unsigned short amiga_freq_lut[(AMIGA_FREQ_TABLE_SIZE / 2) + 1];
unsigned get_amiga_delta(unsigned period)
{
unsigned shamt = clz16(period) - 1;
unsigned p = period << shamt;
unsigned p_frac = p & ((1 << AMIGA_FREQ_TABLE_FRAC_BITS) - 1);
p >>= AMIGA_FREQ_TABLE_FRAC_BITS;
// interpolate table-entries for better result
int f1 = amiga_freq_lut[p - (AMIGA_FREQ_TABLE_SIZE / 2)]; // (8363 * 1712) / float(p);
int f2 = amiga_freq_lut[p + 1 - (AMIGA_FREQ_TABLE_SIZE / 2)]; // (8363 * 1712) / float(p + 1);
unsigned frequency = (f1 << AMIGA_FREQ_TABLE_FRAC_BITS) + (f2 - f1) * p_frac;
if (shamt > AMIGA_FREQ_TABLE_FRAC_BITS) frequency <<= shamt - AMIGA_FREQ_TABLE_FRAC_BITS;
else frequency >>= AMIGA_FREQ_TABLE_FRAC_BITS - shamt;
// BEHOLD: the expression of the devil
// quasi-explaination: the table-lookup the playback freq - the LUT presc - make it overflow - round it - pick the top
frequency = ((long long)frequency * unsigned(((1.0 / SAMPLERATE) * (1 << 6)) * (1LL << 32)) + (1ULL << 31)) >> 32;
return frequency;
}
float get_normal_noise()
{
float r = 0.0;
......@@ -88,6 +33,18 @@ float get_normal_noise()
return r;
}
template <typename T>
void print_lut(T *lut, size_t size)
{
for (size_t i = 0; i < size; ++i)
{
printf("%d, ", lut[i]);
}
}
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define PRINT_LUT(x) print_lut(x, ARRAY_SIZE(x))
int main(int argc, char *argv[])
{
/*
......@@ -102,6 +59,10 @@ int main(int argc, char *argv[])
{
linear_freq_lut[i] = unsigned(float(pow(2.0, i / 768.0) * 8363.0 / (1 << 8)) * float(1 << 9) + 0.5);
}
// dump it
printf("u16 linear_freq_lut[%d] = {\n", ARRAY_SIZE(linear_freq_lut));
PRINT_LUT(linear_freq_lut);
printf("};\n\n");
// generate a lut for amiga frequencies
for (unsigned i = 0; i < (AMIGA_FREQ_TABLE_SIZE / 2) + 1; ++i)
......@@ -109,7 +70,12 @@ int main(int argc, char *argv[])
unsigned p = i + (AMIGA_FREQ_TABLE_SIZE / 2);
amiga_freq_lut[i] = (unsigned short)(((8363 * 1712) / float((p * 32768) / AMIGA_FREQ_TABLE_SIZE)) * (1 << 6) + 0.5);
}
#if 1
// dump it
printf("u16 amiga_freq_lut[%d] = {\n", ARRAY_SIZE(amiga_freq_lut));
PRINT_LUT(amiga_freq_lut);
printf("};\n\n");
#if 0
for (unsigned period = 1; period < 32767; period += 17)
{
float frequency1 = (8363 * 1712) / float(period);
......
#ifndef _CONFIG_H_
#define _CONFIG_H_
#ifndef _PIMP_CONFIG_H_
#define _PIMP_CONFIG_H_
#define CYCLES_PR_FRAME 280896
/* 32 is the maximum amount of channels in fasttracker2. a nice default. */
#define CHANNELS 32
/* check the sample-rate calculator at http://www.pineight.com/gba/samplerates/ for more glitch-free samplerates */
#define SAMPLERATE 18157
#endif /* _CONFIG_H_ */
/* only 130 bytes big, quite damn pleasing results */
#define AMIGA_FREQ_TABLE_LOG_SIZE 7
/* derivated settings. don't touch. */
#define SOUND_BUFFER_SIZE (CYCLES_PR_FRAME / ((1 << 24) / SAMPLERATE))
#define AMIGA_FREQ_TABLE_SIZE (1 << AMIGA_FREQ_TABLE_LOG_SIZE)
#define AMIGA_FREQ_TABLE_FRAC_BITS (15 - AMIGA_FREQ_TABLE_LOG_SIZE)
#endif /* _PIMP_CONFIG_H_ */
#ifndef _INTERNAL_H_
#define _INTERNAL_H_
#ifndef _PIMP_INTERNAL_H_
#define _PIMP_INTERNAL_H_
#include "config.h"
......@@ -140,4 +140,4 @@ typedef enum
91: "set surround sound" ???
*/
#endif /* _INTERNAL_H_ */
#endif /* _PIMP_INTERNAL_H_ */
#ifndef _MIXER_H_
#define _MIXER_H_
#ifndef _PIMP_MIXER_H_
#define _PIMP_MIXER_H_
#include <gba_base.h>
#define CHANNELS 32
#define SOUND_BUFFER_SIZE 304
#include "config.h"
namespace mixer
{
typedef enum
{
LOOP_TYPE_NONE,
LOOP_TYPE_FORWARD,
LOOP_TYPE_PINGPONG
} loop_type_t;
typedef struct sample_
{
u32 len;
u32 loop_start;
u32 loop_end;
loop_type_t loop_type;
const u8 *data;
} sample_t;
typedef struct channel_state_
{
sample_t *sample;
u32 sample_cursor;
s32 sample_cursor_delta;
u32 volume;
} channel_t;
extern volatile channel_t channels[CHANNELS];
void reset();
void mix(s8 *target, size_t samples);
u32 mix_samples(s32 *target, u32 samples, const u8 *sample_data, u32 vol, u32 sample_cursor, s32 sample_cursor_delta);
typedef enum
{
LOOP_TYPE_NONE,
LOOP_TYPE_FORWARD,
LOOP_TYPE_PINGPONG
} loop_type_t;
typedef struct sample_
{
u32 len;
u32 loop_start;
u32 loop_end;
loop_type_t loop_type;
const u8 *data;
} sample_t;
typedef struct channel_state_
{
sample_t *sample;
u32 sample_cursor;
s32 sample_cursor_delta;
u32 volume;
} channel_t;
extern volatile channel_t channels[CHANNELS];
void reset();
void mix(s8 *target, size_t samples);
u32 mix_samples(s32 *target, u32 samples, const u8 *sample_data, u32 vol, u32 sample_cursor, s32 sample_cursor_delta);
}
#endif /* _MIXER_H_ */
#endif /* _PIMP_MIXER_H_ */
......@@ -25,10 +25,14 @@
#include "internal.h"
#include "mixer.h"
#include "math.h"
s8 sound_buffers[2][SOUND_BUFFER_SIZE] IWRAM_DATA ALIGN(4);
static u32 sound_buffer_index = 0;
static pimp_channel_t channels[CHANNELS];
u32 samples_per_tick = SOUND_BUFFER_SIZE;
unsigned char *sample_bank;
pimp_module_t *mod;
......@@ -42,6 +46,16 @@ extern "C" void pimp_init(void *module, void *sample_bank)
/* setup timer-shit */
REG_TM0CNT_L = (1 << 16) - ((1 << 24) / SAMPLERATE);
REG_TM0CNT_H = TIMER_START;
for (u32 c = 0; c < 1; ++c)
{
pimp_channel_t &chan = channels[c];
volatile mixer::channel_t &mc = mixer::channels[c];
chan.period = 1000;
chan.effect = EFF_PORTA_DOWN;
chan.porta_speed = 1;
}
}
extern "C" void pimp_close()
......@@ -61,18 +75,6 @@ extern "C" void pimp_vblank()
sound_buffer_index ^= 1;
}
/* Timer = 62610 = 65536 - (16777216 / 5734), buf = 96
Timer = 63940 = 65536 - (16777216 / 10512), buf = 176
Timer = 64282 = 65536 - (16777216 / 13379), buf = 224
Timer = 64612 = 65536 - (16777216 / 18157), buf = 304
Timer = 64738 = 65536 - (16777216 / 21024), buf = 352
Timer = 64909 = 65536 - (16777216 / 26758), buf = 448
Timer = 65004 = 65536 - (16777216 / 31536), buf = 528
Timer = 65073 = 65536 - (16777216 / 36314), buf = 608
Timer = 65118 = 65536 - (16777216 / 40137), buf = 672
Timer = 65137 = 65536 - (16777216 / 42048), buf = 704
Timer = 65154 = 65536 - (16777216 / 43959), buf = 736 */
/*
ideer:
- tick-lengde-tabell i modul-formatet
......@@ -118,8 +120,6 @@ pimp_pattern_entry_t *get_next_pattern_entry(unsigned chan)
return 0;
}
static pimp_channel_t channels[CHANNELS];
void update_row()
{
assert(mod != 0);
......@@ -150,20 +150,15 @@ void update_row()
}
}
u32 samples_per_tick = 200;
static void update_tick()
{
if (mod == 0) return; // no module active (sound-effects can still be playing, though)
// if (mod == 0) return; // no module active (sound-effects can still be playing, though)
for (u32 c = 0; c < CHANNELS; ++c)
{
pimp_channel_t &chan = channels[c];
chan.period = 1000;
chan.effect = EFF_PORTA_UP;
chan.porta_speed = 1;
{
pimp_channel_t &chan = channels[c];
volatile mixer::channel_t &mc = mixer::channels[c];
bool period_dirty = false;
switch (chan.effect)
......@@ -172,11 +167,13 @@ static void update_tick()
case EFF_PORTA_UP:
chan.period += chan.porta_speed;
// if (period < 70) period = 0;
period_dirty = true;
break;
case EFF_PORTA_DOWN:
chan.period -= chan.porta_speed;
if (chan.period < 1) chan.period = 1;
period_dirty = true;
break;
......@@ -193,7 +190,7 @@ static void update_tick()
if (period_dirty)
{
// period to delta-conversion
mc.sample_cursor_delta = get_amiga_delta(chan.period);
}
}
}
......
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