WIP
authorslack <slack@codemaniacs.com>
Fri, 12 Jun 2009 17:25:38 +0000 (19:25 +0200)
committerslack <slack@codemaniacs.com>
Fri, 12 Jun 2009 17:25:38 +0000 (19:25 +0200)
Makefile
play.c
print_sizes.sh
synth.c
synth.h
thesong.c [new file with mode: 0644]
thesong.h

index 92f287015b4ec031076a17c63c5aa58a632674f1..5acfe1bf8aa01375cf1c96ef3d4b12ac695fe21f 100644 (file)
--- 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 d07f2073f86f588903d330f31171b04923561066..3431837f2c3ce6d65632e8d234f842ad9076ad7f 100644 (file)
--- 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];
index 0b5781994c8c0c2a0d74e8aee9451025bba71881..e9424978507a9df876146fd5c60e33fb0699918b 100644 (file)
@@ -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 77cfc825c44e4b0299b00688a4da04351c4ad525..4898b250a02e4a5baf47cf629dc5f730ca0b4750 100644 (file)
--- a/synth.c
+++ b/synth.c
@@ -1,7 +1,7 @@
 #include "synth.h"
 #include <string.h>
 #include <math.h>
-
+#include <stdlib.h>
 
 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; i<len; i++) {
+        uint8 ins = v->ins[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; i<len; i++) {
+            float time=(v->pos+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; i<len; i++) {
-                    v->waves[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; i<len; i++) {
-                    if (op == 2)
-                        v->waves[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; i<len; i++) {
+                case LPF:
+                case HPF:
+                {
+                    // TODO: cutoff should be a wave
+                    // op1, op2: cutoff, resonance
+                    float cutoff = detune(1.0f, op1, 0);
+                    float r = (op2)/100.0f;
+
+                    //printf("op1=%d, op2=%d, cutoff=%f; r=%f\n", op1, op2, cutoff, r);
+                    
                     float sample = v->waves[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 32611be1da5567eac897015c004aaf3ce1296a48..045e62e6d1733a096352762f65497cf57b903958 100644 (file)
--- 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 (file)
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
+};
+
+
index 93bf344034743fe87fcdee66cb12d974d6baab52..9a22004fc6773124031718af6ce4a4a26640e8a3 100644 (file)
--- 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