attempt at tracker style music
main.cpp
- Committer:
- spinal
- Date:
- 2019-02-07
- Revision:
- 15:209481812170
- Parent:
- 13:8ce494870ba6
File content as of revision 15:209481812170:
#include "Pokitto.h" #include "HWSound.h" #include "snd.h" #include "tune.h" #include "gfx.h" Pokitto::Core mygame; Pokitto::Display d; typedef struct{ bool playSample; int soundPoint; const uint8_t *currentSound; uint32_t currentSoundSize; int volume; int speed; int repeat; } sampletype; sampletype snd[4]; // up to 4 sounds at once? int oldQuart; uint32_t nextBufferIndexToFill = 0; uint32_t nextT = 0; uint32_t oldBufIndex=0; int currentLine=0; int mytick=0; int pattern=0; uint32_t myDelay; uint32_t tempTime; uint32_t sndTime; Ticker sounder; Ticker sounder1; bool playMusic = 1; const char *noteNames[] = {"--","C ","C#","D ","D#","E ","F ","F#","G ","G#","A ","A#","B "}; const int note_speed[]={ 16,17,18,19,20,21,23,24,25,27,29,30, // C, C#, D, D#, E, F, F#, G, G#, A, A#, B, 32,34,36,38,40,43,45,48,51,54,57,60, 64,68,72,76,81,85,91,96,102,108,114,121, 128,136,144,152,161,171,181,192,203,215,228,242, 256,271,287,304,323,342,362,384,406,431,456,483, 512,542,575,609,645,683,724,767,813,861,912,967, 1024,1085,1149,1218,1290,1367,1448,1534,1625,1722,1825,1933, 2048,2170,2299,2435,2580,2734,2896,3068,3251,3444,3649,3866, 4096,4339,4598,4871,5161,5467,5793,6137,6502,6889,7298,7732,}; // new playsound function uint8_t playSound(int channel, const unsigned char *sound, int volume = 255, int speed=255, int repeat=0){ // get sound length int soundSize = 0; for(int t=0; t<4; t++){ soundSize <<= 8; soundSize |= sound[t] & 0xFF; } int sampleRate = 0; for(int t=0; t<2; t++){ sampleRate <<= 8; sampleRate |= sound[t+4] & 0xFF; } float spd = (POK_AUD_FREQ / (float)sampleRate); snd[channel].currentSound = sound; // sound to play snd[channel].volume = volume; // volume snd[channel].speed = (speed/spd); // recalculated above snd[channel].currentSoundSize = soundSize; // length of sound array adjusted for speed change snd[channel].soundPoint = 0; // where the current sound is upto snd[channel].repeat = repeat; // repeat point snd[channel].playSample = 1; // trigger sample playing return channel; } uint8_t mixSound(int samplePos) { int temp = 0; signed int ss[4]; for(int s=0; s<4; s++){ int currentPos = (snd[s].soundPoint*snd[s].speed)>>8; ss[s] = snd[s].currentSound[currentPos] -127; ss[s] *= snd[s].volume; ss[s] /= 256; ss[s] *= snd[s].playSample; // will be 1 or 0, if not playing, will silence snd[s].soundPoint++; if( currentPos >= snd[s].currentSoundSize){ if(snd[s].repeat){ snd[s].soundPoint=0; }else{ snd[s].playSample=0; snd[s].soundPoint=0; } } } temp = (ss[0] + ss[1] + ss[2] + ss[3])/4; return temp +127; } void update_tune(){ if(playMusic==1){ char pat = my_pattern[pattern]; int special = 0; for(int t=0; t<4; t++){ int note = tune[pat][currentLine][t][0]; int octave = tune[pat][currentLine][t][1]; // no longer used int volume = tune[pat][currentLine][t][2];// max volume from xm/mod was 64 int instrument = tune[pat][currentLine][t][3]; special = tune[pat][currentLine][t][4]; if(special == 22){ // 22 = F in MOD format. 0.02 = 1 'tick' sounder.detach(); sounder.attach(&update_tune, 0.02 * tune[pat][currentLine][t][5]); // speed of song } // if valid volume change, change it, if not use previous if(volume >=128){ volume -=128; volume *= 4; }else{ // don't change volume volume = snd[t].volume; } if(note > 0){ //int speed = (note_speed[note-1] << octave) /2; int speed = note_speed[note-1]; for(int s=1; s<octave; s++){ speed *=2; } switch(instrument){ case 1: playSound(t, s_01, volume, speed, sampleRepeat[instrument-1]); break; case 2: playSound(t, s_02, volume, speed, sampleRepeat[instrument-1]); break; case 3: playSound(t, s_03, volume, speed, sampleRepeat[instrument-1]); break; case 4: playSound(t, s_04, volume, speed, sampleRepeat[instrument-1]); break; case 5: playSound(t, s_05, volume, speed, sampleRepeat[instrument-1]); break; case 6: playSound(t, s_06, volume, speed, sampleRepeat[instrument-1]); break; case 7: playSound(t, s_07, volume, speed, sampleRepeat[instrument-1]); break; case 8: playSound(t, s_08, volume, speed, sampleRepeat[instrument-1]); break; case 9: playSound(t, s_09, volume, speed, sampleRepeat[instrument-1]); break; case 10: playSound(t, s_10, volume, speed, sampleRepeat[instrument-1]); break; case 11: playSound(t, s_11, volume, speed, sampleRepeat[instrument-1]); break; case 12: playSound(t, s_12, volume, speed, sampleRepeat[instrument-1]); break; case 13: playSound(t, s_13, volume, speed, sampleRepeat[instrument-1]); break; } } snd[t].volume = volume; } // patterns are 64 lines long, or until special code 20. if(currentLine++==63 || special == 20){ currentLine=0; if(++pattern>=sizeof(my_pattern))pattern=0; } } // playMusic } int beatCounter; void update_buffer(){ int quart = soundbufindex / 512; int sndOffset[]={1024,1536,0,512}; if(oldQuart != quart){ oldQuart = quart; for(int t=0; t<=SBUFSIZE/4;){ uint8_t sample = mixSound(t); soundbuf[t+sndOffset[quart]] = sample; t++; } // if(beatCounter++==3){ // beatCounter=0; // update_tune(); // } } } // print text void print(uint16_t x, uint16_t y, const char* text){ for(uint8_t t = 0; t < strlen(text); t++){ uint8_t character = text[t]; d.drawBitmap(x,y,tinyfont[character]); x += 4; } } int main () { mygame.begin(); mygame.setFrameRate(255); // Init audio stream. pokPlayStream(); // activate stream mygame.sound.ampEnable(true); mygame.sound.playMusicStream(); sounder.attach(&update_tune, 0.08); // speed of song d.load565Palette(&tinyfont_pal[0]); while (mygame.isRunning()) { update_buffer(); if (mygame.update()) { d.color = 1; //d.printf("Pattern %d\n", pattern); //d.printf("Line %d\n", currentLine); char pat = my_pattern[pattern]; char tempText[20]; int s1=currentLine-5; if(s1<0)s1=0; int s2 = currentLine+5; if(s2>63)s2=63; sprintf(tempText,"T[%2d] P[%2d] L[%2d]",pattern,pat,currentLine); print(0,0,tempText); int s; for(s=s1; s<s2; s++){ for(int t=0; t<4; t++){ int note = tune[pat][s][t][0]; int octave = tune[pat][s][t][1]; // no longer used int volume = tune[pat][s][t][2];// max volume from xm/mod was 64 int instrument = tune[pat][s][t][3]; int special = tune[pat][s][t][4]; if(volume >=128){ volume -=128; } int x1 = t*27; int y1 = ((8-currentLine)+s)*6; if(s == currentLine || s == currentLine+1){ d.setColor(5); d.drawLine(0, y1-1, 219, y1-1); } print(x1,y1,noteNames[note]); sprintf(tempText,"%d",octave); print(x1 + 8,y1,tempText); sprintf(tempText,"%d",volume); print(x1 + 12,y1,tempText); sprintf(tempText,"%2d|",instrument); print(x1 + 16,y1,tempText); } } } } }