From 1a78b47b9116a6a3eae64e10e661ba97ca18f3f5 Mon Sep 17 00:00:00 2001 From: slack Date: Fri, 12 Jun 2009 19:25:38 +0200 Subject: [PATCH] WIP --- Makefile | 5 ++- play.c | 1 + print_sizes.sh | 17 ++++++-- synth.c | 108 ++++++++++++++++++++++++++++--------------------- synth.h | 18 ++++++--- thesong.c | 22 ++++++++++ thesong.h | 23 +++-------- 7 files changed, 121 insertions(+), 73 deletions(-) create mode 100644 thesong.c diff --git a/Makefile b/Makefile index 92f2870..5acfe1b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=gcc -m32 -CFLAGS=-std=c99 -Os -Wall -s \ +CFLAGS=-std=c99 -Os -Wall -g \ -march=pentium4 -ffast-math -nodefaultlibs \ -fomit-frame-pointer -fno-strict-aliasing -fno-common \ -fpeephole2 -fexpensive-optimizations -frerun-cse-after-loop \ @@ -13,11 +13,12 @@ all: lolailo gzip -c lolailo > lolailo.gz ls -l lolailo.gz -lolailo: lolailo.o synth.o play.o +lolailo: lolailo.o synth.o play.o thesong.o lolailo.o: lolailo.c synth.h sizedtypes.h play.h thesong.h song.h play.o: play.c sizedtypes.h play.h synth.h song.h synth.o: synth.c synth.h sizedtypes.h +thesong.o: thesong.c thesong.h song.h sizedtypes.h clean: rm -f *.o lolailo lolailo.gz diff --git a/play.c b/play.c index d07f207..3431837 100644 --- a/play.c +++ b/play.c @@ -70,6 +70,7 @@ void play(void *s, uint8 *stream, int len) uint8 j = last_voice_used; last_voice_used = (last_voice_used + 1) % NUM_VOICES; + memset(&voices[j], 0, sizeof(Voice)); voices[j].pitch = detune(440.0f,note-21,0); voices[j].pos = buf_start; voices[j].ins = &song->instrument_data[cur_trk->instrument]; diff --git a/print_sizes.sh b/print_sizes.sh index 0b57819..e942497 100644 --- a/print_sizes.sh +++ b/print_sizes.sh @@ -1,5 +1,16 @@ #!/bin/bash -python -c "print 'play() ->', 0x$(objdump -t play.o | grep play$ | awk '{print $5}'), 'bytes'" -python -c "print 'synth() ->', 0x$(objdump -t synth.o | grep synth$ | awk '{print $5}'), 'bytes'" -python -c "print 'thesong ->', 0x$(objdump -t lolailo.o | grep thesong$ | awk '{print $5}'), 'bytes'" +for i in *.o; do + objcopy -O binary $i $i.bin + ORIG_SIZE=$(cat $i.bin | wc -c) + 7z a -tGZIP -mx=9 -mfb=64 $i.bin.gz $i.bin > /dev/null + COMPRESSED_SIZE=$(cat $i.bin.gz | wc -c) + printf "%10s: %4d -> %4d bytes\n" ${i%.o} $ORIG_SIZE $COMPRESSED_SIZE +done +cat *.bin > all.bin +ORIG_SIZE=$(cat all.bin | wc -c) +7z a -tGZIP -mx=9 -mfb=64 all.bin.gz all.bin > /dev/null +COMPRESSED_SIZE=$(cat all.bin.gz | wc -c) +printf "%10s: %d -> %d bytes\n" TOTAL $ORIG_SIZE $COMPRESSED_SIZE +rm *.bin +rm *.bin.gz diff --git a/synth.c b/synth.c index 77cfc82..4898b25 100644 --- a/synth.c +++ b/synth.c @@ -1,7 +1,7 @@ #include "synth.h" #include #include - +#include float detune(float base, int coarse, int fine) { @@ -19,52 +19,69 @@ uint8 synth(Voice *v, int len, float *mix_buf) int iPC=0; // instrument program counter int wave=0; while (1) { - uint8 op = v->ins[iPC++]; - //printf("wave %d, op=%d\n", wave, op); - - switch (op) { - /* - case 0: // CONSTANT - { - float value = ((int8) v->ins[iPC++]/127.0); - for (int i=0; iins[iPC++]; + uint8 op1 = v->ins[iPC++]; + uint8 op2 = v->ins[iPC++]; + //printf("wave %d, ins=%d (%d, %d)\n", wave, ins, op1, op2); + for (int i=0; ipos+i)*invSAMPLE_RATE; + switch (ins) { + case CONST: + { + float value = ((int8) op1/100.0); v->waves[wave][i] = value; + break; } - } - */ - case 1: // SINE - { - int8 coarse = v->ins[iPC++]; - int8 fine = v->ins[iPC++]; - float pitch = detune(v->pitch, coarse, fine); - for (int i=0; iwaves[wave][i] = 0.5f*sinf(pitch*TWOPI_samplerate*(v->pos+i)); + + case SINE: + { + // op1: signed coarse detune, op2: signed fine detune + float pitch = detune(v->pitch, (int8) op1, (int8) op2); + v->waves[wave][i] = sinf(pitch*TWOPI*time); + break; } - break; - } - - case 2: // SUM - case 3: // RING - { - uint8 wave1 = v->ins[iPC++]; - uint8 wave2 = v->ins[iPC++]; - for (int i=0; iwaves[wave][i] = v->waves[wave1][i]+v->waves[wave2][i]; + + case SQUARE: + { + float pitch = detune(v->pitch, (int8) op1, 0); + float pw = op2/100.0f; + float period = 1.0/pitch; + if (fmodf(time, period) > (period*pw)) + v->waves[wave][i] = 1.0f; else - v->waves[wave][i] = v->waves[wave1][i]*v->waves[wave2][i]; + v->waves[wave][i] = -1.0f; + break; + } + case NOISE: + v->waves[wave][i] = rand()/(float)RAND_MAX; + break; + /* + case TO_0_1: + v->waves[wave][i] = v->waves[wave][i-1]*0.5f+0.5f; + break; + */ + + case SUM: + case MUL: + { + // op1,2: wave indices to sum/mul + if (ins == SUM) + v->waves[wave][i] = v->waves[op1][i]+v->waves[op2][i]; + else + v->waves[wave][i] = v->waves[op1][i]*v->waves[op2][i]; + break; } - break; - } - - case 4: // LPF - case 5: // HPF - { - // TODO: cutoff should be a wave - float cutoff = detune(440.0f, v->ins[iPC++], 0); - float r = 1.0f/(v->ins[iPC++]); - for (int i=0; iwaves[wave-1][i]; // Compute filter coefficients @@ -73,7 +90,7 @@ uint8 synth(Voice *v, int len, float *mix_buf) // Extraemos algunos calculos que son redundantes en HP y LP float param_tan = PI_samplerate * cutoff; - if (op==4) { // Low-pass + if (ins==LPF) { // Low-pass c=1.0f / tanf(param_tan); c2 = c*c; @@ -103,13 +120,12 @@ uint8 synth(Voice *v, int len, float *mix_buf) data[1]=data[0]; v->waves[wave][i] = data[0]; + break; } - break; + default: + goto end; } - default: - goto end; } - ++wave; } diff --git a/synth.h b/synth.h index 32611be..045e62e 100644 --- a/synth.h +++ b/synth.h @@ -7,8 +7,10 @@ #define SAMPLE_RATE 44100.0f #define MAX_OPS 30 #define PI 3.1415926535897931f +#define TWOPI 6.2831853071795862f #define PI_samplerate 7.10487365723e-05f #define TWOPI_samplerate 0.000142097473145f +#define invSAMPLE_RATE 0.000022675736961451248f /* An instrument is defined a FORTH-like stack of several operations between @@ -42,11 +44,17 @@ typedef struct float waves[MAX_OPS][BUFFER_SIZE]; } Voice; -#define SINE(detune_coarse, detune_fine) 1,detune_coarse,detune_fine -#define SUM(a,b) 2,a,b -#define MUL(a,b) 3,a,b -#define LPF(cutoff, resonance) 4, cutoff,resonance -#define HPF(cutoff, resonance) 5, cutoff,resonance +#define CONST 0 +#define SINE 1 +#define SQUARE 2 +#define SAW 3 +#define SUM 4 +#define MUL 5 +#define LPF 6 +#define HPF 7 +#define TO_0_1 8 +#define NOISE 9 +#define END 255 extern uint8 synth(Voice *v, int len, float *mix_buf); extern float detune(float base, int coarse, int fine); diff --git a/thesong.c b/thesong.c new file mode 100644 index 0000000..6eb55a6 --- /dev/null +++ b/thesong.c @@ -0,0 +1,22 @@ +#include "thesong.h" +#include "synth.h" + +Song thesong={ + { // begin patterns + {0x01, 0x00, 0x00, 0x00}, + }, // end patterns + { // begin tracks + {{45,0,0,0,43,0,0,0,41,0,0,0,40,0,0,0}, 0}, + }, // end tracks + { // begin instrument data + SINE,-70,0, + NOISE,0,0, + MUL,0,1, + END, + }, // end instrument data + { // begin playlist + 0,255, + }, // end playlist +}; + + diff --git a/thesong.h b/thesong.h index 93bf344..9a22004 100644 --- a/thesong.h +++ b/thesong.h @@ -1,20 +1,9 @@ +#ifndef THESONG_H +#define THESONG_H + #include "song.h" -Song thesong={ - { // begin patterns - {0x01, 0x00, 0x00, 0x00}, - }, // end patterns - { // begin tracks - {{45,0,0,0,43,0,0,0,41,0,0,0,40,0,0,0}, 0}, - }, // end tracks - { // begin instrument data - SINE(0,0), - SINE(-70,0), // LFO - MUL(0,1), - 255, - }, // end instrument data - { // begin playlist - 0,255, - }, // end playlist -}; +extern Song thesong; + +#endif -- 2.34.1