Imported player code from the old synth, compiles but there is nothing to synthesize yet
authorslack <slack@codemaniacs.com>
Wed, 10 Jun 2009 23:19:54 +0000 (01:19 +0200)
committerslack <slack@codemaniacs.com>
Wed, 10 Jun 2009 23:19:54 +0000 (01:19 +0200)
play.cpp
play.h
song.h [new file with mode: 0644]
synth.cpp
synth.h
track.h [deleted file]
trackerwindow.h

index 70e3229e285775fb1d83040c9b7f494259dcaadb..735ca41409bfbcb9cfa210e8d03a628a3eb1f685 100644 (file)
--- a/play.cpp
+++ b/play.cpp
+#include "sizedtypes.h"
 #include "play.h"
-
+#include "synth.h"
+#include "song.h"
 #include <cstdio>
 #include <cstring>
 
-void play(void *songdata, uint8* stream, int len)
+#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)
 {
-    memset(stream, 0, len);
-    //printf("Sound callback\n");
+       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; i<NUM_RHYTHM_CHANNELS; ++i) {
+                       int steps;
+                       steps = song->rhythms[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; i<NUM_CHANNELS; ++i) {
+                       unsigned int chanval=song->patterns[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; i<num_samples; ++i)
+       {
+               float tmp = mix_buf[i];
+               if (tmp>1.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.h b/play.h
index 3a0459813270fcd0e79bec65adb9aaeee3407114..adc13cb5741c58ad3f7e788d52f9e1501e5a3842 100644 (file)
--- a/play.h
+++ b/play.h
@@ -3,10 +3,6 @@
 
 #include "sizedtypes.h"
 
-struct Song
-{
-};
-
 void play(void *songdata, uint8 *stream, int len);
 
 #endif // PLAY_H
diff --git a/song.h b/song.h
new file mode 100644 (file)
index 0000000..78ef440
--- /dev/null
+++ b/song.h
@@ -0,0 +1,36 @@
+#ifndef SONG_H
+#define SONG_H
+
+#include "sizedtypes.h"
+
+// uncompressed song size == 
+//          NUM_PATTERNS*NUM_CHANNELS
+//          + NUM_TRACKS*TRACK_LENGTH
+//          + INSTRUMENT_DATA_LENGTH
+//          + PLAYLIST_LENGTH
+
+#define NUM_PATTERNS 20
+#define NUM_CHANNELS 10
+#define NUM_TRACKS 20
+#define TRACK_LENGTH 16
+#define INSTRUMENT_DATA_LENGTH 100
+#define PLAYLIST_LENGTH 50
+
+struct Track
+{
+       uint8 notes[TRACK_LENGTH];
+       uint8 instrument;
+};
+
+struct Song
+{
+       uint8 patterns[NUM_PATTERNS][NUM_CHANNELS];
+       Track tracks[NUM_TRACKS];
+       uint8 instrument_data[INSTRUMENT_DATA_LENGTH];
+       uint8 playlist[PLAYLIST_LENGTH];
+};
+
+
+
+#endif
+
index 7569467ce4d941f933bc9e465b709ccbabb68697..34611e4ccb1407c0870510d39bf0f07b29060e9e 100644 (file)
--- a/synth.cpp
+++ b/synth.cpp
@@ -1,2 +1,16 @@
 #include "synth.h"
+#include <cstring>
+#include <cmath>
+
+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 fa4a42c946792e40d55c740df1c587f41541d7ed..075f275b4038dd21a50e3ab0b8de926c2f1cef36 100644 (file)
--- a/synth.h
+++ b/synth.h
@@ -4,6 +4,7 @@
 #include "sizedtypes.h"
 
 #define BUFFER_SIZE 1024
+#define SAMPLE_RATE 44100.0f
 #define MAX_OPS 30
 
 /*
@@ -39,7 +40,8 @@ struct Voice
 };
 
 
-void synth(Voice *v, int len, float *mix_buf);
+extern bool synth(Voice *v, int len, float *mix_buf);
+extern const float detune(int coarse, int fine);
 
 
 
diff --git a/track.h b/track.h
deleted file mode 100644 (file)
index 6a44678..0000000
--- a/track.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef TRACK_H
-#define TRACK_H
-
-class Track
-{
-public:
-    Track();
-};
-
-#endif // TRACK_H
index a8538af8441a0dd12356256b8eae941aed8d080a..f4bf05eddc9fe0a7d395d5bf05a5e77c9420dd3b 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <QWidget>
 #include <QPaintEvent>
+#include "song.h"
+#include "sizedtypes.h"
 
 class TrackerWindow : public QWidget
 {
@@ -10,9 +12,13 @@ class TrackerWindow : public QWidget
 
     public:
     TrackerWindow(QWidget *parent);
+       void setSong(Song *song) { theSong = song; }
+       void setPattern(uint8 pat) { currentPattern = pat; }
 
     private:
     void paintEvent(QPaintEvent *);
+       Song *theSong;
+       uint8 currentPattern;
 };
 
 #endif // TRACKERWINDOW_H