attempt at tracker style music
main.cpp@15:209481812170, 2019-02-07 (annotated)
- Committer:
- spinal
- Date:
- Thu Feb 07 11:02:56 2019 +0000
- Revision:
- 15:209481812170
- Parent:
- 13:8ce494870ba6
ReDo of my music player, with a nice long song.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Pokitto | 0:2d2a3994d55d | 1 | #include "Pokitto.h" |
spinal | 13:8ce494870ba6 | 2 | #include "HWSound.h" |
spinal | 13:8ce494870ba6 | 3 | #include "snd.h" |
spinal | 13:8ce494870ba6 | 4 | #include "tune.h" |
spinal | 15:209481812170 | 5 | #include "gfx.h" |
Pokitto | 0:2d2a3994d55d | 6 | |
Pokitto | 0:2d2a3994d55d | 7 | Pokitto::Core mygame; |
spinal | 12:37d999e445ad | 8 | Pokitto::Display d; |
Pokitto | 0:2d2a3994d55d | 9 | |
spinal | 12:37d999e445ad | 10 | |
spinal | 13:8ce494870ba6 | 11 | typedef struct{ |
spinal | 13:8ce494870ba6 | 12 | bool playSample; |
spinal | 13:8ce494870ba6 | 13 | int soundPoint; |
spinal | 13:8ce494870ba6 | 14 | const uint8_t *currentSound; |
spinal | 15:209481812170 | 15 | uint32_t currentSoundSize; |
spinal | 13:8ce494870ba6 | 16 | int volume; |
spinal | 13:8ce494870ba6 | 17 | int speed; |
spinal | 13:8ce494870ba6 | 18 | int repeat; |
spinal | 13:8ce494870ba6 | 19 | } sampletype; |
spinal | 13:8ce494870ba6 | 20 | |
spinal | 13:8ce494870ba6 | 21 | sampletype snd[4]; // up to 4 sounds at once? |
spinal | 13:8ce494870ba6 | 22 | int oldQuart; |
spinal | 13:8ce494870ba6 | 23 | |
spinal | 13:8ce494870ba6 | 24 | uint32_t nextBufferIndexToFill = 0; |
spinal | 13:8ce494870ba6 | 25 | uint32_t nextT = 0; |
spinal | 15:209481812170 | 26 | uint32_t oldBufIndex=0; |
spinal | 13:8ce494870ba6 | 27 | |
spinal | 13:8ce494870ba6 | 28 | int currentLine=0; |
spinal | 13:8ce494870ba6 | 29 | int mytick=0; |
spinal | 15:209481812170 | 30 | int pattern=0; |
spinal | 15:209481812170 | 31 | |
spinal | 15:209481812170 | 32 | uint32_t myDelay; |
spinal | 15:209481812170 | 33 | uint32_t tempTime; |
spinal | 15:209481812170 | 34 | uint32_t sndTime; |
spinal | 15:209481812170 | 35 | |
spinal | 13:8ce494870ba6 | 36 | |
spinal | 15:209481812170 | 37 | Ticker sounder; |
spinal | 15:209481812170 | 38 | Ticker sounder1; |
spinal | 15:209481812170 | 39 | |
spinal | 15:209481812170 | 40 | bool playMusic = 1; |
spinal | 15:209481812170 | 41 | |
spinal | 15:209481812170 | 42 | const char *noteNames[] = {"--","C ","C#","D ","D#","E ","F ","F#","G ","G#","A ","A#","B "}; |
spinal | 13:8ce494870ba6 | 43 | |
spinal | 15:209481812170 | 44 | const int note_speed[]={ |
spinal | 15:209481812170 | 45 | 16,17,18,19,20,21,23,24,25,27,29,30, // C, C#, D, D#, E, F, F#, G, G#, A, A#, B, |
spinal | 15:209481812170 | 46 | 32,34,36,38,40,43,45,48,51,54,57,60, |
spinal | 15:209481812170 | 47 | 64,68,72,76,81,85,91,96,102,108,114,121, |
spinal | 15:209481812170 | 48 | 128,136,144,152,161,171,181,192,203,215,228,242, |
spinal | 15:209481812170 | 49 | 256,271,287,304,323,342,362,384,406,431,456,483, |
spinal | 15:209481812170 | 50 | 512,542,575,609,645,683,724,767,813,861,912,967, |
spinal | 15:209481812170 | 51 | 1024,1085,1149,1218,1290,1367,1448,1534,1625,1722,1825,1933, |
spinal | 15:209481812170 | 52 | 2048,2170,2299,2435,2580,2734,2896,3068,3251,3444,3649,3866, |
spinal | 15:209481812170 | 53 | 4096,4339,4598,4871,5161,5467,5793,6137,6502,6889,7298,7732,}; |
spinal | 11:a573cacdc078 | 54 | |
spinal | 15:209481812170 | 55 | // new playsound function |
spinal | 15:209481812170 | 56 | uint8_t playSound(int channel, const unsigned char *sound, int volume = 255, int speed=255, int repeat=0){ |
spinal | 15:209481812170 | 57 | |
spinal | 15:209481812170 | 58 | // get sound length |
spinal | 15:209481812170 | 59 | int soundSize = 0; |
spinal | 15:209481812170 | 60 | for(int t=0; t<4; t++){ |
spinal | 15:209481812170 | 61 | soundSize <<= 8; |
spinal | 15:209481812170 | 62 | soundSize |= sound[t] & 0xFF; |
spinal | 13:8ce494870ba6 | 63 | } |
spinal | 13:8ce494870ba6 | 64 | |
spinal | 15:209481812170 | 65 | int sampleRate = 0; |
spinal | 15:209481812170 | 66 | for(int t=0; t<2; t++){ |
spinal | 15:209481812170 | 67 | sampleRate <<= 8; |
spinal | 15:209481812170 | 68 | sampleRate |= sound[t+4] & 0xFF; |
spinal | 13:8ce494870ba6 | 69 | } |
spinal | 13:8ce494870ba6 | 70 | |
spinal | 15:209481812170 | 71 | float spd = (POK_AUD_FREQ / (float)sampleRate); |
spinal | 15:209481812170 | 72 | |
spinal | 15:209481812170 | 73 | snd[channel].currentSound = sound; // sound to play |
spinal | 15:209481812170 | 74 | snd[channel].volume = volume; // volume |
spinal | 15:209481812170 | 75 | snd[channel].speed = (speed/spd); // recalculated above |
spinal | 15:209481812170 | 76 | snd[channel].currentSoundSize = soundSize; // length of sound array adjusted for speed change |
spinal | 15:209481812170 | 77 | snd[channel].soundPoint = 0; // where the current sound is upto |
spinal | 15:209481812170 | 78 | snd[channel].repeat = repeat; // repeat point |
spinal | 15:209481812170 | 79 | snd[channel].playSample = 1; // trigger sample playing |
spinal | 15:209481812170 | 80 | |
spinal | 15:209481812170 | 81 | return channel; |
spinal | 15:209481812170 | 82 | |
spinal | 13:8ce494870ba6 | 83 | } |
spinal | 13:8ce494870ba6 | 84 | |
spinal | 13:8ce494870ba6 | 85 | |
spinal | 13:8ce494870ba6 | 86 | uint8_t mixSound(int samplePos) |
spinal | 13:8ce494870ba6 | 87 | { |
spinal | 13:8ce494870ba6 | 88 | int temp = 0; |
spinal | 15:209481812170 | 89 | signed int ss[4]; |
spinal | 13:8ce494870ba6 | 90 | for(int s=0; s<4; s++){ |
spinal | 15:209481812170 | 91 | int currentPos = (snd[s].soundPoint*snd[s].speed)>>8; |
spinal | 15:209481812170 | 92 | ss[s] = snd[s].currentSound[currentPos] -127; |
spinal | 15:209481812170 | 93 | ss[s] *= snd[s].volume; |
spinal | 15:209481812170 | 94 | ss[s] /= 256; |
spinal | 15:209481812170 | 95 | ss[s] *= snd[s].playSample; // will be 1 or 0, if not playing, will silence |
spinal | 15:209481812170 | 96 | snd[s].soundPoint++; |
spinal | 15:209481812170 | 97 | if( currentPos >= snd[s].currentSoundSize){ |
spinal | 13:8ce494870ba6 | 98 | if(snd[s].repeat){ |
spinal | 13:8ce494870ba6 | 99 | snd[s].soundPoint=0; |
spinal | 13:8ce494870ba6 | 100 | }else{ |
spinal | 13:8ce494870ba6 | 101 | snd[s].playSample=0; |
spinal | 13:8ce494870ba6 | 102 | snd[s].soundPoint=0; |
spinal | 13:8ce494870ba6 | 103 | } |
spinal | 13:8ce494870ba6 | 104 | } |
spinal | 15:209481812170 | 105 | } |
spinal | 15:209481812170 | 106 | temp = (ss[0] + ss[1] + ss[2] + ss[3])/4; |
spinal | 15:209481812170 | 107 | return temp +127; |
spinal | 13:8ce494870ba6 | 108 | } |
spinal | 13:8ce494870ba6 | 109 | |
spinal | 13:8ce494870ba6 | 110 | void update_tune(){ |
spinal | 12:37d999e445ad | 111 | |
spinal | 15:209481812170 | 112 | if(playMusic==1){ |
spinal | 15:209481812170 | 113 | |
spinal | 15:209481812170 | 114 | char pat = my_pattern[pattern]; |
spinal | 15:209481812170 | 115 | |
spinal | 15:209481812170 | 116 | int special = 0; |
spinal | 15:209481812170 | 117 | for(int t=0; t<4; t++){ |
spinal | 15:209481812170 | 118 | int note = tune[pat][currentLine][t][0]; |
spinal | 15:209481812170 | 119 | int octave = tune[pat][currentLine][t][1]; // no longer used |
spinal | 15:209481812170 | 120 | int volume = tune[pat][currentLine][t][2];// max volume from xm/mod was 64 |
spinal | 15:209481812170 | 121 | int instrument = tune[pat][currentLine][t][3]; |
spinal | 15:209481812170 | 122 | special = tune[pat][currentLine][t][4]; |
spinal | 15:209481812170 | 123 | |
spinal | 15:209481812170 | 124 | if(special == 22){ |
spinal | 15:209481812170 | 125 | // 22 = F in MOD format. 0.02 = 1 'tick' |
spinal | 15:209481812170 | 126 | sounder.detach(); |
spinal | 15:209481812170 | 127 | sounder.attach(&update_tune, 0.02 * tune[pat][currentLine][t][5]); // speed of song |
spinal | 15:209481812170 | 128 | } |
spinal | 15:209481812170 | 129 | |
spinal | 15:209481812170 | 130 | |
spinal | 15:209481812170 | 131 | // if valid volume change, change it, if not use previous |
spinal | 15:209481812170 | 132 | if(volume >=128){ |
spinal | 15:209481812170 | 133 | volume -=128; |
spinal | 15:209481812170 | 134 | volume *= 4; |
spinal | 15:209481812170 | 135 | }else{ |
spinal | 15:209481812170 | 136 | // don't change volume |
spinal | 15:209481812170 | 137 | volume = snd[t].volume; |
spinal | 15:209481812170 | 138 | } |
spinal | 15:209481812170 | 139 | |
spinal | 13:8ce494870ba6 | 140 | |
spinal | 15:209481812170 | 141 | if(note > 0){ |
spinal | 15:209481812170 | 142 | |
spinal | 15:209481812170 | 143 | //int speed = (note_speed[note-1] << octave) /2; |
spinal | 15:209481812170 | 144 | int speed = note_speed[note-1]; |
spinal | 15:209481812170 | 145 | for(int s=1; s<octave; s++){ |
spinal | 15:209481812170 | 146 | speed *=2; |
spinal | 15:209481812170 | 147 | } |
spinal | 15:209481812170 | 148 | |
spinal | 15:209481812170 | 149 | switch(instrument){ |
spinal | 15:209481812170 | 150 | case 1: playSound(t, s_01, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 151 | case 2: playSound(t, s_02, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 152 | case 3: playSound(t, s_03, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 153 | case 4: playSound(t, s_04, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 154 | case 5: playSound(t, s_05, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 155 | case 6: playSound(t, s_06, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 156 | case 7: playSound(t, s_07, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 157 | case 8: playSound(t, s_08, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 158 | case 9: playSound(t, s_09, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 159 | case 10: playSound(t, s_10, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 160 | case 11: playSound(t, s_11, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 161 | case 12: playSound(t, s_12, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 162 | case 13: playSound(t, s_13, volume, speed, sampleRepeat[instrument-1]); break; |
spinal | 15:209481812170 | 163 | } |
spinal | 13:8ce494870ba6 | 164 | } |
spinal | 15:209481812170 | 165 | |
spinal | 15:209481812170 | 166 | snd[t].volume = volume; |
spinal | 15:209481812170 | 167 | |
spinal | 13:8ce494870ba6 | 168 | } |
spinal | 15:209481812170 | 169 | |
spinal | 15:209481812170 | 170 | // patterns are 64 lines long, or until special code 20. |
spinal | 15:209481812170 | 171 | if(currentLine++==63 || special == 20){ |
spinal | 15:209481812170 | 172 | currentLine=0; |
spinal | 15:209481812170 | 173 | if(++pattern>=sizeof(my_pattern))pattern=0; |
spinal | 15:209481812170 | 174 | } |
spinal | 15:209481812170 | 175 | |
spinal | 15:209481812170 | 176 | } // playMusic |
spinal | 15:209481812170 | 177 | } |
spinal | 15:209481812170 | 178 | |
spinal | 15:209481812170 | 179 | |
spinal | 15:209481812170 | 180 | int beatCounter; |
spinal | 15:209481812170 | 181 | void update_buffer(){ |
spinal | 15:209481812170 | 182 | |
spinal | 15:209481812170 | 183 | int quart = soundbufindex / 512; |
spinal | 15:209481812170 | 184 | int sndOffset[]={1024,1536,0,512}; |
spinal | 15:209481812170 | 185 | |
spinal | 15:209481812170 | 186 | if(oldQuart != quart){ |
spinal | 15:209481812170 | 187 | oldQuart = quart; |
spinal | 15:209481812170 | 188 | for(int t=0; t<=SBUFSIZE/4;){ |
spinal | 15:209481812170 | 189 | uint8_t sample = mixSound(t); |
spinal | 15:209481812170 | 190 | soundbuf[t+sndOffset[quart]] = sample; |
spinal | 15:209481812170 | 191 | t++; |
spinal | 15:209481812170 | 192 | } |
spinal | 15:209481812170 | 193 | // if(beatCounter++==3){ |
spinal | 15:209481812170 | 194 | // beatCounter=0; |
spinal | 15:209481812170 | 195 | // update_tune(); |
spinal | 15:209481812170 | 196 | // } |
spinal | 13:8ce494870ba6 | 197 | } |
spinal | 15:209481812170 | 198 | |
spinal | 15:209481812170 | 199 | } |
spinal | 15:209481812170 | 200 | |
spinal | 15:209481812170 | 201 | // print text |
spinal | 15:209481812170 | 202 | void print(uint16_t x, uint16_t y, const char* text){ |
spinal | 15:209481812170 | 203 | for(uint8_t t = 0; t < strlen(text); t++){ |
spinal | 15:209481812170 | 204 | uint8_t character = text[t]; |
spinal | 15:209481812170 | 205 | d.drawBitmap(x,y,tinyfont[character]); |
spinal | 15:209481812170 | 206 | x += 4; |
spinal | 13:8ce494870ba6 | 207 | } |
spinal | 13:8ce494870ba6 | 208 | } |
spinal | 12:37d999e445ad | 209 | |
spinal | 12:37d999e445ad | 210 | |
spinal | 12:37d999e445ad | 211 | int main () |
spinal | 12:37d999e445ad | 212 | { |
spinal | 12:37d999e445ad | 213 | mygame.begin(); |
spinal | 15:209481812170 | 214 | mygame.setFrameRate(255); |
spinal | 13:8ce494870ba6 | 215 | |
spinal | 13:8ce494870ba6 | 216 | // Init audio stream. |
spinal | 13:8ce494870ba6 | 217 | pokPlayStream(); // activate stream |
spinal | 13:8ce494870ba6 | 218 | mygame.sound.ampEnable(true); |
spinal | 13:8ce494870ba6 | 219 | mygame.sound.playMusicStream(); |
spinal | 15:209481812170 | 220 | |
spinal | 15:209481812170 | 221 | sounder.attach(&update_tune, 0.08); // speed of song |
spinal | 15:209481812170 | 222 | |
spinal | 15:209481812170 | 223 | |
spinal | 15:209481812170 | 224 | d.load565Palette(&tinyfont_pal[0]); |
spinal | 11:a573cacdc078 | 225 | |
spinal | 12:37d999e445ad | 226 | while (mygame.isRunning()) |
spinal | 12:37d999e445ad | 227 | { |
spinal | 15:209481812170 | 228 | update_buffer(); |
spinal | 15:209481812170 | 229 | |
spinal | 12:37d999e445ad | 230 | if (mygame.update()) |
spinal | 12:37d999e445ad | 231 | { |
spinal | 12:37d999e445ad | 232 | d.color = 1; |
spinal | 15:209481812170 | 233 | //d.printf("Pattern %d\n", pattern); |
spinal | 15:209481812170 | 234 | //d.printf("Line %d\n", currentLine); |
spinal | 15:209481812170 | 235 | |
spinal | 15:209481812170 | 236 | char pat = my_pattern[pattern]; |
spinal | 15:209481812170 | 237 | |
spinal | 15:209481812170 | 238 | char tempText[20]; |
spinal | 15:209481812170 | 239 | |
spinal | 15:209481812170 | 240 | int s1=currentLine-5; |
spinal | 15:209481812170 | 241 | if(s1<0)s1=0; |
spinal | 15:209481812170 | 242 | int s2 = currentLine+5; |
spinal | 15:209481812170 | 243 | if(s2>63)s2=63; |
spinal | 15:209481812170 | 244 | |
spinal | 15:209481812170 | 245 | sprintf(tempText,"T[%2d] P[%2d] L[%2d]",pattern,pat,currentLine); |
spinal | 15:209481812170 | 246 | print(0,0,tempText); |
spinal | 15:209481812170 | 247 | |
spinal | 15:209481812170 | 248 | int s; |
spinal | 15:209481812170 | 249 | for(s=s1; s<s2; s++){ |
spinal | 15:209481812170 | 250 | |
spinal | 15:209481812170 | 251 | for(int t=0; t<4; t++){ |
spinal | 15:209481812170 | 252 | int note = tune[pat][s][t][0]; |
spinal | 15:209481812170 | 253 | int octave = tune[pat][s][t][1]; // no longer used |
spinal | 15:209481812170 | 254 | int volume = tune[pat][s][t][2];// max volume from xm/mod was 64 |
spinal | 15:209481812170 | 255 | int instrument = tune[pat][s][t][3]; |
spinal | 15:209481812170 | 256 | int special = tune[pat][s][t][4]; |
spinal | 15:209481812170 | 257 | |
spinal | 15:209481812170 | 258 | if(volume >=128){ |
spinal | 15:209481812170 | 259 | volume -=128; |
spinal | 15:209481812170 | 260 | } |
spinal | 15:209481812170 | 261 | |
spinal | 15:209481812170 | 262 | int x1 = t*27; |
spinal | 15:209481812170 | 263 | int y1 = ((8-currentLine)+s)*6; |
spinal | 15:209481812170 | 264 | |
spinal | 15:209481812170 | 265 | if(s == currentLine || s == currentLine+1){ |
spinal | 15:209481812170 | 266 | d.setColor(5); |
spinal | 15:209481812170 | 267 | d.drawLine(0, y1-1, 219, y1-1); |
spinal | 15:209481812170 | 268 | } |
spinal | 15:209481812170 | 269 | |
spinal | 15:209481812170 | 270 | print(x1,y1,noteNames[note]); |
spinal | 15:209481812170 | 271 | sprintf(tempText,"%d",octave); |
spinal | 15:209481812170 | 272 | print(x1 + 8,y1,tempText); |
spinal | 15:209481812170 | 273 | sprintf(tempText,"%d",volume); |
spinal | 15:209481812170 | 274 | print(x1 + 12,y1,tempText); |
spinal | 15:209481812170 | 275 | sprintf(tempText,"%2d|",instrument); |
spinal | 15:209481812170 | 276 | print(x1 + 16,y1,tempText); |
spinal | 15:209481812170 | 277 | |
spinal | 15:209481812170 | 278 | } |
spinal | 15:209481812170 | 279 | } |
spinal | 12:37d999e445ad | 280 | |
spinal | 12:37d999e445ad | 281 | } |
spinal | 12:37d999e445ad | 282 | } |
spinal | 11:a573cacdc078 | 283 | } |
spinal | 11:a573cacdc078 | 284 | |
spinal | 11:a573cacdc078 | 285 |