From 7c24e9a9b02b04dcaf9507acb94091ea70a2c02d Mon Sep 17 00:00:00 2001 From: Xavi Del Campo Date: Fri, 31 Jan 2020 10:32:23 +0100 Subject: Imported pristine psxsdk-20190410 from official repo --- libmodplay/Makefile | 38 ++++++ libmodplay/mod.c | 328 +++++++++++++++++++++++++++++++++++++++++++++++ libmodplay/modplay.c | 290 +++++++++++++++++++++++++++++++++++++++++ libmodplay/modplay.h | 222 ++++++++++++++++++++++++++++++++ libmodplay/modplay_int.h | 20 +++ libmodplay/modtbl.h | 62 +++++++++ 6 files changed, 960 insertions(+) create mode 100644 libmodplay/Makefile create mode 100644 libmodplay/mod.c create mode 100644 libmodplay/modplay.c create mode 100644 libmodplay/modplay.h create mode 100644 libmodplay/modplay_int.h create mode 100644 libmodplay/modtbl.h (limited to 'libmodplay') diff --git a/libmodplay/Makefile b/libmodplay/Makefile new file mode 100644 index 0000000..af4a8e5 --- /dev/null +++ b/libmodplay/Makefile @@ -0,0 +1,38 @@ +# Makefile for libmodplay + +include ../Makefile.cfg + +CFLAGS += -I../libadpcm + +all: libmodplay.a libmodplay_nopsx.a + +modplay.o: modplay.c + $(CC) $(CFLAGS) -c modplay.c + +mod.o: mod.c + $(CC) $(CFLAGS) -c mod.c + +libmodplay.a: modplay.o mod.o + rm -f libmodplay.a + $(AR) r libmodplay.a modplay.o mod.o + $(RANLIB) libmodplay.a + +modplay_nopsx.o: modplay.c + $(HOST_CC) $(HOST_CFLAGS) -DNO_PSX_LIB -c modplay.c -o modplay_nopsx.o + +mod_nopsx.o: mod.c + $(HOST_CC) $(HOST_CFLAGS) -DNO_PSX_LIB -c mod.c -o mod_nopsx.o + +libmodplay_nopsx.a: modplay_nopsx.o mod_nopsx.o + rm -f libmodplay_nopsx.a + $(HOST_AR) r libmodplay_nopsx.a modplay_nopsx.o mod_nopsx.o + $(HOST_RANLIB) libmodplay_nopsx.a + +install: all + cp libmodplay.a $(TOOLCHAIN_PREFIX)/lib + cp modplay.h $(TOOLCHAIN_PREFIX)/include + +clean: + rm -f *.o *.a + +distclean: clean diff --git a/libmodplay/mod.c b/libmodplay/mod.c new file mode 100644 index 0000000..3b569a6 --- /dev/null +++ b/libmodplay/mod.c @@ -0,0 +1,328 @@ +// Ultimate SoundTracker / NoiseTracker / ProTracker module file support for MODPlay + +#include +#include +#include +#include +#include "modplay.h" +#include "modplay_int.h" +#include "modtbl.h" // Period -> frequency table for ProTracker MODs + +ModMusic *MODLoad_MOD(void *d) +{ + unsigned char *c = d; + ModMusic *m; + int x; + int mp=0; + int y; + +// Allocate memory for mod structure + m = (ModMusic*)malloc(sizeof(ModMusic)); + +// Get title + memcpy(m->title, &c[0], 20); + +// For now let's assume there are 32 samples... + mp+=20; + + memcpy(m->id, &c[0x438], 4); + +// If there is not a valid ID, this is the start of pattern data, +// otherwise jump four bytes + + if(strncmp(m->id, "M.K.",4) == 0 || strncmp(m->id, "FLT4", 4) == 0 || + strncmp(m->id, "M!K!",4) == 0 || strncmp(m->id, "4CHN", 4) == 0 || + strncmp(m->id, "6CHN", 4) == 0 || strncmp(m->id, "8CHN", 4) == 0) + m->sample_num = 31; + else + m->sample_num = 15; + +// Standard channel number is 4 + + if(strncmp(m->id, "6CHN", 4) == 0) + m->channel_num = 6; + else if(strncmp(m->id, "8CHN", 4) == 0) + m->channel_num = 8; + else + m->channel_num = 4; + +// Get sample information + + m->sample = malloc(sizeof(ModSample) * m->sample_num); + + for(x = 0; x < m->sample_num; x++) + { + // Get sample name + memcpy(m->sample[x].name, &c[mp], 22); + mp+=22; + // Get sample length + m->sample[x].length = (c[mp] << 8) | c[mp+1]; + m->sample[x].length*= 2; + mp+=2; + // Get finetune value + m->sample[x].finetune = c[mp] & 0xf; + + if(m->sample[x].finetune & 0x8) + m->sample[x].finetune|=0xf0; + + mp++; + // Get sample volume + m->sample[x].volume = c[mp]; + mp++; + + // Get sample repeat offset + m->sample[x].repeat_off = (c[mp] << 8) | c[mp+1]; + m->sample[x].repeat_off *= 2; + mp+=2; + + // Get sample repeat length + m->sample[x].repeat_len = (c[mp] << 8) | c[mp+1]; + m->sample[x].repeat_len *= 2; + mp+=2; + + // Samples are always 8-bit + m->sample[x].bits = 8; + + // Data type is always 0 + m->sample[x].data_type = 0; + } + +// Get number of song positons + m->song_pos_num = c[mp++]; + +// Ignore this value... + mp++; + +// Get pattern table + memcpy(m->pattern_tbl, &c[mp], 128); + mp+=128; + + + +// Get ID (it is not assured that this value will be valid) + memcpy(m->id, &c[0x438], 4); +// If there is not a valid ID, this is the start of pattern data, +// otherwise jump four bytes + + if(strncmp(m->id, "M.K.",4) == 0 || strncmp(m->id, "FLT4", 4) == 0 || + strncmp(m->id, "M!K!",4) == 0 || strncmp(m->id, "4CHN", 4) == 0 || + strncmp(m->id, "6CHN", 4) == 0 || strncmp(m->id, "8CHN", 4) == 0) + mp+=4; + +// Get number of patterns +// This is actually done by scanning the pattern table for the highest value + y = 0; + + for(x=0;x<128;x++) + { + //printf("%x, \n", m->pattern_tbl[x]); + if(m->pattern_tbl[x] > y) + y = m->pattern_tbl[x]; + } + + //printf("\n"); + + m->pattern_num = y+1; + +// Pattern row sizes are always 64 + for(x = 0; x < m->pattern_num; x++) + m->pattern_row_num[x] = 64; + +// Allocate memory for patterns... + m->pattern_data = malloc(m->pattern_num * ((4*m->channel_num)*64)); + +// Get pattern data + memcpy(m->pattern_data,&c[mp], m->pattern_num * ((4*m->channel_num)*64)); + mp += m->pattern_num * ((4*m->channel_num)*64); + +// Allocate & Get sample data + for(x = 0; x < m->sample_num; x++) + { + if(m->sample[x].length < 32 || (modload_flags & MODLOAD_NOSAMPLES)) + m->sample[x].data = NULL; + else + { + m->sample[x].data = malloc(m->sample[x].length); + memcpy(m->sample[x].data, &c[mp], m->sample[x].length); + + // Convert to unsigned 8-bit format + // Most sound cards/programs nowadays want data in this format + for(y = 0; y < m->sample[x].length; y++) + m->sample[x].data[y] ^= 0x80; + } + + mp += m->sample[x].length; + } + + m->song_pos = 0; + m->pat_pos = 0; + m->divisions_sec = 7; + m->beats_minute = 125; + m->ticks_division = 6; + + for(x = 0; x<8;x++) + { + m->old_samples[x] = 1; + m->old_periods[x] = 0; + } + + m->cur_tick = 0; + m->fmt = MOD_FMT_MOD; +// MOD has no instruments! + m->instrument_num = 0; + + return m; +} + +void MODPlay_MOD(ModMusic *m,int *t) +{ + int cur_pat = m->pattern_tbl[m->song_pos]; + int cur_pat_pos = m->pat_pos; + unsigned char b[4]; + int s, p, e,x,y; + int do_not_increase_pat = 0; + int v1,f; + + if(*t == 0) + return; + + + m->cur_tick++; + + if(m->cur_tick != (50 / m->divisions_sec)) + return; + + for(x = 0; x < m->channel_num; x++) + { + memcpy(b, &m->pattern_data[(cur_pat * ((4*m->channel_num)*64)) + (cur_pat_pos * (4*m->channel_num)) + (x*4)], 4); + + // Get sample + s = (b[2] & 0xf0)>>4; + s |= b[0] & 0xf0; + + // Get period + p = b[1]; + p|= (b[0] & 0xf)<<8; + p&=~(2048|1024); + + // Get effect + e = b[3]; + e|= (b[2] & 0xf)<<8; + + if(s != 0 && p==0) + p = m->old_periods[x]; + + if(s == 0 && p != 0) + s=m->old_samples[x]; + + v1 = m->sample[s-1].volume; + + switch(e & 0xf00) + { + case 0xc00: // Set volume + v1 = e & 0xff; + break; + } + + f = -1; + + for(y = 0; y < sizeof(modplay_pitch_per_tbl) / 4; y++) + { + if(modplay_pitch_per_tbl[y<<1] == p) + { + f = modplay_pitch_per_tbl[(y<<1)+1]; + break; + } + } + + if(f==-1 && p!=0) + { + printf("Couldn't find period %d in table. Calculating it.\n", p); + f = SsFreqToPitch(7159090/(p*2)); + } + + f+=m->transpose; + + if(f<0)f=0; + else if(f>0x3fff)f=0x3fff; + + v1 <<= 8; + + if(v1 >= 0x4000) + v1 = 0x3fff; + + + if(s && p!=0) + { + if(x == 0 || x == 3 || x == 4 || x == 7) + MODPlay_func(m, x, s-1, f, v1, 0); + else + MODPlay_func(m, x, s-1, f, 0, v1); + } + + switch(e & 0xf00) + { + case 0xb00: // Position Jump + m->song_pos = e & 0xff; + m->pat_pos = 0; + // printf("Jump to song pos %d\n", m->song_pos); + + // this fixes some mods which jump over the mod itself + + if(m->song_pos >= m->song_pos_num) + m->song_pos = 0; + + do_not_increase_pat = 1; + break; + case 0xd00: // Pattern break + m->song_pos++; + m->pat_pos = (((e&0xf0)>>4)*10)+(e&0xf); + // printf("Pattern break, newpatpos=%d\n", m->pat_pos); + + // this fixes some mods which jump over themselves + + if(m->song_pos >= m->song_pos_num) + m->song_pos = 0; + + do_not_increase_pat = 1; + break; + case 0xf00: // Tempo + /*v1 = (e & 0xf0) >> 4; + v2 = e & 0xf; + v3 = (v1*16)+v2;*/ + + if((e & 0xff) <= 32) + { + if((e&0xff) == 0)e++; + m->ticks_division = e & 0xff; + } + else + m->beats_minute = e & 0xff; + + m->divisions_sec = 24 * m->beats_minute; + m->divisions_sec /= m->ticks_division; + m->divisions_sec /= 60; + break; + } + + if(s) m->old_samples[x] = s; + if(p) m->old_periods[x] = p; + + m->cur_tick = 0; + } + + if(!do_not_increase_pat)m->pat_pos++; + + if(m->pat_pos == 64) + { + m->song_pos++; + if(m->song_pos >= m->song_pos_num) + { + *t-=1; + + MODRewind(m); + } + + m->pat_pos = 0; + } +} diff --git a/libmodplay/modplay.c b/libmodplay/modplay.c new file mode 100644 index 0000000..9f5f33d --- /dev/null +++ b/libmodplay/modplay.c @@ -0,0 +1,290 @@ +// MODplay for the PS1 +// Music Module Player +// Supports ProTracker (.mod) module format + +// Requires libADPCM! + +// If NO_PSX_LIB is defined, no parts using PSXSDK functions are compiled +// This is useful if you want to use the library to handle module files in tools + +#ifndef NO_PSX_LIB +#include +#endif + +#include +#include +#include +#include + +#ifndef NO_PSX_LIB +#include +#endif + +#include "modplay.h" +#include "modplay_int.h" + +// Configuration defines + +// Size of ADPCM buffer used by MODUploadSamples when +// converting 8-bit unsigned PCM samples to PS1 ADPCM format +// By default it is set to 0x4000, 16 kilobytes + +#define ADPCM_BUFFER_SIZE 0x4000 + + + +int modplay_base_voice = 0; +int modplay_max_vol = 0x3fff; +int modplay_chan_vols[8]; +int modplay_int_cnt = 0; +int modplay_samples_off[32]; +int modplay_chan_mask = 0; +int modplay_is_mono = 0; +unsigned char modplay_adpcm_buffer[ADPCM_BUFFER_SIZE]; + +unsigned int modload_flags = 0; + +ModMusic *MODLoad(void *d) +{ + return MODLoadEx(d, 0); +} + +ModMusic *MODLoadEx(void *d, unsigned int flags) +{ + modload_flags = flags; + + // If the module file was in no other format, assume the module file is + // in ProTracker format. There's no real way to detect a ProTracker module + // file 100% correctly so this will do. + + return MODLoad_MOD(d); +} + +void MODUnload(ModMusic *m) +{ + int x; + + MODStop(m); + + switch(m->fmt) + { + case MOD_FMT_MOD: + free(m->pattern_data); + + for(x = 0; x < m->sample_num; x++) + { + if(m->sample[x].data != NULL) + free(m->sample[x].data); + } + + free(m->sample); + + free(m); + break; + } + +} + +#ifdef NO_PSX_LIB +void MODPlay_func(ModMusic *m, int c, int s, int p, int vl, int vr) +{ + // Just a stub +} +#else +void MODPlay_func(ModMusic *m, int c, int s, int p, int vl, int vr) +{ + int v = c + modplay_base_voice; +// static int mask = 0; + +// if(s != -1) +// { + // SsKeyOff(v); + if(p != -1) + SsVoicePitch(v, p); +// } + + if(modplay_max_vol != 0x3fff) + { + vl = (modplay_max_vol * vl) / 0x4000; + vr = (modplay_max_vol * vr) / 0x4000; + vl&=0x3fff; + vr&=0x3fff; + } + + if(modplay_is_mono) + { + if(vl>vr) + vr=vl; + else + vl=vr; + } + + SsVoiceVol(v, vl, vr); + + if(s != -1) + { + if(modplay_samples_off[s] != -1) + { + SsVoiceStartAddr(v, modplay_samples_off[s]); + modplay_chan_mask|=(1<fmt) + { + case MOD_FMT_MOD: + MODPlay_MOD(m, t); + break; + } + + //printf("modplay_chan_mask = %d\n", modplay_chan_mask); +#ifndef NO_PSX_LIB + SsKeyOnMask(modplay_chan_mask); +#endif +} + +void MODStop(ModMusic *m) +{ +#ifndef NO_PSX_LIB + int mask = 0; + int x; + + for(x = 0; xchannel_num; x++) + mask|=1<<(modplay_base_voice+x); + + SsKeyOffMask(mask); +#endif +} + +#ifndef NO_PSX_LIB +int MODUploadSamples(ModMusic *m, int base_addr) +{ + int x, b; + + if(base_addr == -1) + base_addr = SPU_DATA_BASE_ADDR; + + modplay_samples_off[0] = base_addr; + + for(x = 0; x < m->sample_num; x++) + { + b = SsAdpcmPack(m->sample[x].data, modplay_adpcm_buffer, + m->sample[x].length, FMT_U8, sizeof(modplay_adpcm_buffer), 0); + SsUpload(modplay_adpcm_buffer, b, modplay_samples_off[x]); + + if(x!=30) + modplay_samples_off[x+1] = modplay_samples_off[x]+b; + } + + return modplay_samples_off[x]; +} + +int MOD4PSX_Upload(void *d, int base_addr) +{ + unsigned char *c = d; + int x; + int o; + int sz; + int n; + int smpOff; + +// Check magic string + + if(strncmp((char*)c, "_mod4psx", 8) != 0) + return -1; + + o = 12; + n = *((int*)(c+8)); + + if(base_addr == -1) + smpOff = SPU_DATA_BASE_ADDR; + else + smpOff = base_addr; + + //smpOff = modplay_samples_off[0]; + + printf("Number of samples: %d\n", n); + + for(x = 0; x < n; x++) + { +// Get size + sz = *((int*)(c+o)); + printf("Size: %d\n", sz); +// Ignore eight reserved bytes (for future expension) + o+=12; + + if(sz > 0) + { + modplay_samples_off[x] = smpOff; + + SsUpload(c+o, sz, modplay_samples_off[x]); + + smpOff+=sz; + } + else + modplay_samples_off[x] = -1; + + o += sz; + } + + return modplay_samples_off[x]; +} + +#endif + +void MODSetBaseVoice(int base_voice) +{ + modplay_base_voice = base_voice; +} + +void MODSetMaxVolume(unsigned short max_volume) +{ + // Default is 0x3fff. + // Valid values 0 (MUTE) - 0x3FFF (MAX) + + modplay_max_vol = max_volume & 0x3fff; +} + +void MODRewind(ModMusic *m) +{ + MODStop(m); + m->song_pos = 0; + m->pat_pos = 0; + + if(m->fmt == MOD_FMT_MOD) + { + m->divisions_sec = 7; + m->beats_minute = 125; + m->ticks_division = 6; + } +} + +void MODSetTranspose(ModMusic *m, short transpose) +{ + m->transpose = transpose; +} + +void MODSetMono(int value) +{ + /* Sets mono audio mode + left volume = right volume */ + + modplay_is_mono = value; +} + +#ifdef NO_PSX_LIB + +// Some code might use this, so use a stub. + +unsigned short SsFreqToPitch(int hz) +{ + return 0; +} + +#endif diff --git a/libmodplay/modplay.h b/libmodplay/modplay.h new file mode 100644 index 0000000..0370bc6 --- /dev/null +++ b/libmodplay/modplay.h @@ -0,0 +1,222 @@ +#ifndef _MODPLAY_H +#define _MODPLAY_H + +#ifndef NO_PSX_LIB + #include +#endif + +/** Format identification IDs. */ + +enum modplay_formats +{ + MOD_FMT_MOD, /** Ultimate SoundTracker / NoiseTracker / ProTracker */ +}; + +typedef struct +{ + char name[32]; + unsigned int length; // Length in bytes + char finetune; + unsigned char volume; + unsigned int repeat_off; + unsigned int repeat_len; + unsigned char bits; + unsigned char data_type; + unsigned char *data; +}ModSample; + +/** Instrument. */ + +typedef struct +{ + char name[64]; + int sample_num; + unsigned char sample_ids[8]; +}ModInstrument; + +/** Music */ + +typedef struct +{ + /** Music title. */ + char title[32]; + /** Number of samples in the music */ + int sample_num; + /** Number of channels used by the music */ + int channel_num; + /** Number of instruments used by the music */ + int instrument_num; + /** Pointer to an array of ModSample structures. */ + ModSample *sample; + /** Pointer to an array of ModInstrument structures. */ + ModInstrument *instrument; + /** Number of song positions. */ + unsigned char song_pos_num; + /** Pattern table. */ + unsigned char pattern_tbl[256]; + /** Number of rows for each pattern. */ + unsigned char pattern_row_num[256]; + /** ID, such as "M!K!","M.K.","FLT4", etc. */ + char id[4]; + /** Number of patterns. */ + int pattern_num; + /** Pointer to pattern data */ + unsigned char *pattern_data; + /** Format of music. */ + int fmt; + + /** [Runtime] Current song position */ + unsigned char song_pos; + /** [Runtime] Position inside the pattern currently being played */ + unsigned char pat_pos; + /** [Runtime] Divisions per second */ + int divisions_sec; + /** [Runtime] Beats per minute */ + unsigned char beats_minute; + /** [Runtime] Ticks per division */ + unsigned char ticks_division; + /** [Runtime] Current tick count */ + unsigned char cur_tick; + /** [Runtime] Old periods for each channel. */ + unsigned short old_periods[8]; + /** [Runtime] Old sample numbers for each channel. */ + unsigned char old_samples[8]; + /** [Runtime] In PlayStation pitch, this is added to the original sample pitch + and can be used to change the pitch of the music for special effects */ + short transpose; +}ModMusic; + +/** Flags for MODLoad */ +enum modload_flags +{ + /** Do not load the samples in memory */ + MODLOAD_NOSAMPLES = 1, +}; + +/** + * Allocate a ModMusic structure and copy data to it from + * data in memory containing a music module file + * + * Almost all data from the music module file is copied into another location + * in memory for the ModMusic structure. + * + * This means your free memory should be roughly the double of + * the size of the MOD you're loading. + * + * You can avoid loading the samples in the module file's native format, + * thus saving useful memory, by passing the MODLOAD_NOSAMPLES + * flag. This is especially the case when you use MOD4PSX_Upload(). + * + * @param d Pointer to a buffer containing a music module file + * @param flags Flag bitmask. + * @return Pointer to newly allocated ModMusic structure. + */ + +ModMusic *MODLoadEx(void *d, unsigned int flags); + +/** + * Just like MODLoadEx() but with the flags parameters set to zero, i.e. + * default behaviour. + * + * @param d Pointer to a buffer containing a music module file + * @return Pointer to newly allocated ModMusic structure. + */ + +ModMusic *MODLoad(void *d); + +/** + * Play a tick of a music. + * + * This has to be called 60 / 50 times per second. + * + * MODPlay decreases the value referenced by t every time + * the music finishes. + * + * Set the variable pointed by t when you want to set the number of times again! + * + * @param m Pointer to ModMusic structure + * @param t Pointer to an int which contains how many times the music module has to be played. + * i.e. if *t == 1, play once, if *t == 2, play twice, ..., if *t == -1, loop endlessly + * + */ + +void MODPlay(ModMusic *m,int *t); + +/** + * Stop a music. + * @param m Pointer to ModMusic structure for the music. + */ +void MODStop(ModMusic *m); + +/** + * Rewind music, that is, make it restart from the beginning. + * @param m Pointer to ModMusic structure for the music. + */ +void MODRewind(ModMusic *m); + +/** + * Upload the samples of the module music to Sound RAM + * @param m Pointer to ModMusic structure for the music. + * @param base_addr Sound RAM address to start from when uploading to Sound RAM + * If -1 it is interpreted to be the same as the start of the section for sound data in Sound RAM + * (SPU_DATA_BASE_ADDR). base_addr must be a multiply of 8. + * @return The sound address after all the uploaded samples + */ + +int MODUploadSamples(ModMusic *m, int base_addr); + +/** + * Sets the SPU voice to use as the first channel when playing music. + * + * The voice for the second channel will then be this (value+1), and so on... + * + * Usually the base voice is 0; a MOD file can have up to eight channels, so take care of that. + * + * @param base_voice Desired base voice (0-23) + */ + +void MODSetBaseVoice(int base_voice); + +/** + * Sets transpose for music + * + * Changing the transpose value for a music shifts the frequency + * its samples are played at, but the music's tempo is unchanged. + * @param m Pointer to ModMusic structure + * @param transpose Transpose value + */ + +void MODSetTranspose(ModMusic *m, short transpose); + +/** + * Upload preconverted ADPCM samples, as generated by the mod4psx tool. + * + * @param d Pointer to buffer containing the ADPCM samples archive + * @param base_addr Base address at which the samples will start to be uploaded. + * @return The sound address after all the uploaded samples + */ + +int MOD4PSX_Upload(void *d, int base_addr); + +/** + * Free memory allocated for music module + * @param m Pointer to ModMusic structure + */ + +void MODUnload(ModMusic *m); + +/** + * Set maximum volume for MODPlay + * @param max_volume Maximum volume desired (0-0x3FFF) + */ + +void MODSetMaxVolume(unsigned short max_volume); + +/** + * Set mono mode + * @param value If 0 set stereo mode, if 1 set mono mode + */ + +void MODSetMono(int value); + +#endif diff --git a/libmodplay/modplay_int.h b/libmodplay/modplay_int.h new file mode 100644 index 0000000..9a8a124 --- /dev/null +++ b/libmodplay/modplay_int.h @@ -0,0 +1,20 @@ +/** + * MODPlay: internal prototypes + */ + +#ifndef _MODPLAY_INT_H +#define _MODPLAY_INT_H + +void MODPlay_func(ModMusic *m, int c, int s, int p, int vl, int vr); +extern int modplay_int_cnt; +extern unsigned int modload_flags; +extern const unsigned short modplay_pitch_per_tbl[120]; + +ModMusic *MODLoad_MOD(void *d); +void MODPlay_MOD(ModMusic *m, int *t); + +#ifdef NO_PSX_LIB +unsigned short SsFreqToPitch(int hz); +#endif + +#endif \ No newline at end of file diff --git a/libmodplay/modtbl.h b/libmodplay/modtbl.h new file mode 100644 index 0000000..96bd407 --- /dev/null +++ b/libmodplay/modtbl.h @@ -0,0 +1,62 @@ +const unsigned short modplay_pitch_per_tbl[120] = { +1712, 194, +1616, 205, +1525, 217, +1440, 230, +1357, 244, +1281, 259, +1209, 274, +1141, 291, +1077, 308, +1017, 326, +961, 345, +907, 366, +856, 388, +808, 411, +762, 436, +720, 461, +678, 490, +640, 519, +604, 550, +570, 583, +538, 617, +508, 654, +480, 692, +453, 733, +428, 776, +404, 822, +381, 872, +360, 923, +339, 980, +320, 1038, +302, 1100, +285, 1166, +269, 1235, +254, 1308, +240, 1385, +226, 1471, +214, 1553, +202, 1645, +190, 1749, +180, 1847, +170, 1955, +160, 2077, +151, 2201, +143, 2324, +135, 2462, +127, 2617, +120, 2770, +113, 2942, +107, 3107, +101, 3291, +95, 3499, +90, 3694, +85, 3911, +80, 4155, +76, 4374, +71, 4682, +67, 4962, +64, 5194, +60, 5541, +57, 5832, +}; -- cgit v1.2.3