From 1081be08a2f405df8e9f137788b2b6f21c2d59cf Mon Sep 17 00:00:00 2001 From: slack Date: Thu, 11 Jun 2009 20:24:43 +0200 Subject: [PATCH] Custom Makefile. First sounds. --- CMakeLists.txt | 23 --------- Makefile | 22 ++++++++ lolailo.cpp => lolailo.c | 24 +++++---- play.c | 107 +++++++++++++++++++++++++++++++++++++++ play.cpp | 105 -------------------------------------- print_sizes.sh | 5 ++ song.h | 12 ++--- synth.c | 65 ++++++++++++++++++++++++ synth.cpp | 16 ------ synth.h | 11 ++-- thesong.h | 22 ++++++++ 11 files changed, 248 insertions(+), 164 deletions(-) delete mode 100644 CMakeLists.txt create mode 100644 Makefile rename lolailo.cpp => lolailo.c (61%) create mode 100644 play.c delete mode 100644 play.cpp create mode 100644 print_sizes.sh create mode 100644 synth.c delete mode 100644 synth.cpp create mode 100644 thesong.h diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 433db7c..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -PROJECT(lolailo) -cmake_minimum_required(VERSION 2.6) -FIND_PACKAGE(Qt4 REQUIRED) -FIND_PACKAGE(SDL REQUIRED) -INCLUDE( ${QT_USE_FILE} ) - -SET(LOLAILO_MOC_HDRS - mainwindow.h - trackerwindow.h -) - -SET(LOLAILO_SOURCES - lolailo.cpp - mainwindow.cpp - play.cpp - synth.cpp - trackerwindow.cpp -) - -QT4_WRAP_CPP(LOLAILO_MOC_SRCS ${LOLAILO_MOC_HDRS}) -ADD_EXECUTABLE(lolailo ${LOLAILO_SOURCES} ${LOLAILO_MOC_SRCS}) -TARGET_LINK_LIBRARIES(lolailo ${QT_LIBRARIES} ${SDL_LIBRARY} SDLmain) - diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c130983 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +CC=gcc -m32 + +CFLAGS=-std=c99 -Os -Wall -s +LDFLAGS=-lSDL-1.2 -nostartfiles + +all: lolailo + bash print_sizes.sh + ls -l lolailo + gzip -c lolailo > lolailo.gz + ls -l lolailo.gz + +lolailo: lolailo.o synth.o play.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 + +clean: + rm -f *.o lolailo lolailo.gz + +.PHONY: clean +.SILENT: diff --git a/lolailo.cpp b/lolailo.c similarity index 61% rename from lolailo.cpp rename to lolailo.c index 473fba1..ce86000 100644 --- a/lolailo.cpp +++ b/lolailo.c @@ -1,10 +1,10 @@ -#include +//#include #include -#include "mainwindow.h" +//#include "mainwindow.h" #include "synth.h" #include "play.h" -Song song; +#include "thesong.h" SDL_AudioSpec desired={44100, AUDIO_S16SYS, @@ -14,18 +14,22 @@ SDL_AudioSpec desired={44100, 0, 0, (void (*)(void *, Uint8 *, int)) play, - &song}; - + &thesong}; +#ifdef DEBUG int main(int argc, char *argv[]) +#else +void _start() +#endif { SDL_Init(SDL_INIT_AUDIO); SDL_OpenAudio(&desired, NULL); SDL_PauseAudio(0); - QApplication a(argc, argv); - MainWindow w(NULL); - w.show(); - int error = a.exec(); + //QApplication a(argc, argv); + //MainWindow w(NULL); + //w.show(); + //int error = a.exec(); + getchar(); SDL_Quit(); - return error; + //return error; } diff --git a/play.c b/play.c new file mode 100644 index 0000000..7f7a9db --- /dev/null +++ b/play.c @@ -0,0 +1,107 @@ +#include "sizedtypes.h" +#include "play.h" +#include "synth.h" +#include "song.h" +#include +#include + + +#define NUM_VOICES 1 + +float row_duration=60.0/360.0; // denominator == RPM +Voice voices[NUM_VOICES]; +float mix_buf[BUFFER_SIZE]={0}; +uint8 last_voice_used=0; + +float current_time=0.0f; +uint32 rows_played=0; // total of rows played +uint8 cur_pos= 0; // current position in the pattern playlist +uint8 cur_row=-1; // current row in the current pattern + +void play(void *s, uint8 *stream, int len) +{ + Song *song = (Song*) s; + int num_samples=len>>1; + int16 *buf=(int16 *)stream; + current_time += num_samples/SAMPLE_RATE; + + memset(mix_buf, 0, BUFFER_SIZE*sizeof(float)); + + if ((current_time - rows_played * row_duration) > row_duration ) { + ++rows_played; + ++cur_row; + int buf_start = ((current_time - rows_played * row_duration)*SAMPLE_RATE)-num_samples; + + if (cur_row == TRACK_LENGTH) { // end of track + cur_row=0; + ++cur_pos; + } + if (song->playlist[cur_pos]==255) { // loop at end of song + cur_pos=0; + } + + uint8 cur_ptn=song->playlist[cur_pos]; + + /* + for (i=0; irhythms[i]; + if (steps & (1<<(15-cur_row))) { + voices[i].pitch = 440.0f*detune(song->rhythm_notes[i]-45,0); + voices[i].pos = buf_start; + voices[i].ins = &song->insts[song->rhythm_insts[i]]; + voices[i].vol = 0.1796875f; + voices[i].active = 1; + } + } + */ + + for (uint8 i=0; ipatterns[cur_ptn][i]; + if (chanval) { + unsigned int trknum=(chanval & 0x0F)-1; + Track *cur_trk = &song->tracks[trknum]; + uint8 trans = (chanval) >> 4; + + unsigned int note = (cur_trk->notes[cur_row] & 0x0F); + if (note) { + float vol = ((cur_trk->notes[cur_row])>>4) * 0.0625f; + note+=trans; + + uint8 j = last_voice_used; + last_voice_used = (last_voice_used + 1) % NUM_VOICES; + voices[j].pitch = 440.0f*detune(note-21,0); + voices[j].pos = buf_start; + voices[j].ins = &song->instrument_data[cur_trk->instrument]; + voices[j].vol = 0.19921875f*vol; + voices[j].active = 1; + } + } + } + + + } + // Ahora vamos sintetizando las voces + for (int i=0; i < NUM_VOICES; ++i) + { + if (voices[i].active) + { + voices[i].active=synth(&voices[i], num_samples, mix_buf); + } + } + + // convertimos a Sint16 + for (int i=0; i1.0f) tmp=1.0f; + else if(tmp<-1.0f) tmp=-1.0f; + buf[i]=(int16)(tmp*32640.0f); + } + +#ifdef OUTFILE + fwrite(buf, sizeof(int16), num_samples, fout); +#endif + +} + diff --git a/play.cpp b/play.cpp deleted file mode 100644 index 735ca41..0000000 --- a/play.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "sizedtypes.h" -#include "play.h" -#include "synth.h" -#include "song.h" -#include -#include - -#define NUM_VOICES 32 - -float row_duration=60.0/90.0; // denominator == BPM -Voice voices[NUM_VOICES]; -float mix_buf[BUFFER_SIZE]={0}; -uint8 last_voice_used=0; - -float current_time=0.0f; -uint32 rows_played=0; // total of rows played -uint8 cur_pos= 0; // current position in the pattern playlist -uint8 cur_row=-1; // current row in the current pattern - -void play(void *s, uint8 *stream, int len) -{ - Song *song = (Song*) s; - unsigned int num_samples=len>>1; - int16 *buf=(int16 *)stream; - current_time += num_samples/SAMPLE_RATE; - - memset(mix_buf, 0, BUFFER_SIZE*sizeof(float)); - - if ((current_time - rows_played * row_duration) > row_duration ) { - ++rows_played; - ++cur_row; - int buf_start = ((current_time - rows_played * row_duration)*SAMPLE_RATE)-num_samples; - - if (cur_row == TRACK_LENGTH) { // end of track - cur_row=0; - ++cur_pos; - } - if (song->playlist[cur_pos]==255) { // loop at end of song - cur_pos=0; - } - - uint8 cur_ptn=song->playlist[cur_pos]; - - /* - for (i=0; irhythms[i]; - if (steps & (1<<(15-cur_row))) { - voices[i].pitch = 440.0f*detune(song->rhythm_notes[i]-45,0); - voices[i].pos = buf_start; - voices[i].ins = &song->insts[song->rhythm_insts[i]]; - voices[i].vol = 0.1796875f; - voices[i].active = 1; - } - } - */ - - for (uint8 i=0; ipatterns[cur_ptn][i]; - unsigned int trknum=chanval & 0x0F; - Track *cur_trk = &song->tracks[trknum]; - uint8 trans = (chanval) >> 4; - - unsigned int note = (cur_trk->notes[cur_row] & 0x0F); - float vol = ((cur_trk->notes[cur_row])>>4) * 0.0625f; - if (chanval) - { - note+=trans; - - uint8 j = last_voice_used; - last_voice_used = (last_voice_used + 1) % NUM_VOICES; - voices[j].pitch = 440.0f*detune(note-45,0); - voices[j].pos = buf_start; - voices[j].ins = &song->instrument_data[cur_trk->instrument]; - voices[j].vol = 0.19921875f*vol; - voices[j].active = 1; - } - } - - - } - // Ahora vamos sintetizando las voces - for (int i=0; i < NUM_VOICES; ++i) - { - if (voices[i].active) - { - voices[i].active=synth(&voices[i], num_samples, mix_buf); - } - } - - // convertimos a Sint16 - for (int i=0; i1.0f) tmp=1.0f; - else if(tmp<-1.0f) tmp=-1.0f; - buf[i]=(int16)(tmp*32640.0f); - } - -#ifdef OUTFILE - fwrite(buf, sizeof(int16), num_samples, fout); -#endif - -} - diff --git a/print_sizes.sh b/print_sizes.sh new file mode 100644 index 0000000..0b57819 --- /dev/null +++ b/print_sizes.sh @@ -0,0 +1,5 @@ +#!/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'" + diff --git a/song.h b/song.h index 78ef440..0e02389 100644 --- a/song.h +++ b/song.h @@ -10,25 +10,25 @@ // + PLAYLIST_LENGTH #define NUM_PATTERNS 20 -#define NUM_CHANNELS 10 -#define NUM_TRACKS 20 +#define NUM_CHANNELS 4 +#define NUM_TRACKS 15 #define TRACK_LENGTH 16 #define INSTRUMENT_DATA_LENGTH 100 #define PLAYLIST_LENGTH 50 -struct Track +typedef struct { uint8 notes[TRACK_LENGTH]; uint8 instrument; -}; +} Track; -struct Song +typedef struct { uint8 patterns[NUM_PATTERNS][NUM_CHANNELS]; Track tracks[NUM_TRACKS]; uint8 instrument_data[INSTRUMENT_DATA_LENGTH]; uint8 playlist[PLAYLIST_LENGTH]; -}; +} Song; diff --git a/synth.c b/synth.c new file mode 100644 index 0000000..d7774c7 --- /dev/null +++ b/synth.c @@ -0,0 +1,65 @@ +#include "synth.h" +#include +#include + +#define PI 3.1415926535897931 + +float detune(int coarse, int fine) +{ + return powf(2.0f, (coarse+(fine/100.0f))/12.0f); +} + +uint8 synth(Voice *v, int len, float *mix_buf) +{ + if (v->pos < 0) { + mix_buf -= v->pos; + len += v->pos; + v->pos = 0; + } + + int iPC=0; // instrument program counter + int wave=0; + while (1) { + uint8 op = v->ins[iPC++]; + + switch (op) { + case 1: // SINE + { + uint8 coarse = v->ins[iPC++]; + uint8 fine = v->ins[iPC++]; + float pitch = v->pitch*detune(coarse, fine); + for (int i=0; iwaves[wave][i] = 0.5f*sinf(pitch*2.0f*PI*(v->pos+i)/SAMPLE_RATE); + } + 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]; + else + v->waves[wave][i] = v->waves[wave1][i]*v->waves[wave2][i]; + } + break; + } + + default: + goto end; + } + + ++wave; + } + +end: + v->pos+=len; + for (int i=0; iwaves[wave-1][i]; + return 1; +} + + diff --git a/synth.cpp b/synth.cpp deleted file mode 100644 index 34611e4..0000000 --- a/synth.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "synth.h" -#include -#include - -const float detune(int coarse, int fine) -{ - return powf(2.0f, (coarse+(fine/100.0f))/12.0f); -} - -bool synth(Voice *v, int len, float *mix_buf) -{ - memset(mix_buf, 0, len*sizeof(float)); - return false; -} - - diff --git a/synth.h b/synth.h index 075f275..17660d7 100644 --- a/synth.h +++ b/synth.h @@ -21,7 +21,7 @@ operation ends the sequence. */ -struct Voice +typedef struct { float pitch; float vol; @@ -37,11 +37,14 @@ struct Voice // buffers generated by wave operations 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 RING(a,b) 3,a,b -extern bool synth(Voice *v, int len, float *mix_buf); -extern const float detune(int coarse, int fine); +extern uint8 synth(Voice *v, int len, float *mix_buf); +extern float detune(int coarse, int fine); diff --git a/thesong.h b/thesong.h new file mode 100644 index 0000000..77abaee --- /dev/null +++ b/thesong.h @@ -0,0 +1,22 @@ +#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(1,10), + //SINE(3,1), + RING(0,1), + RING(1,2), + 255, + }, // end instrument data + { // begin playlist + 0,255, + }, // end playlist +}; + -- 2.34.1