attempt at tracker style music
main.cpp@13:8ce494870ba6, 2018-11-17 (annotated)
- Committer:
- spinal
- Date:
- Sat Nov 17 16:33:51 2018 +0000
- Revision:
- 13:8ce494870ba6
- Parent:
- 12:37d999e445ad
- Child:
- 14:97a5deea7c94
- Child:
- 15:209481812170
having an error with this one
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" |
Pokitto | 0:2d2a3994d55d | 5 | |
Pokitto | 0:2d2a3994d55d | 6 | Pokitto::Core mygame; |
spinal | 12:37d999e445ad | 7 | Pokitto::Display d; |
Pokitto | 0:2d2a3994d55d | 8 | |
spinal | 13:8ce494870ba6 | 9 | //------------------------[ Button handling, very accurate ]------------------------ |
spinal | 13:8ce494870ba6 | 10 | #define HELD 0 |
spinal | 13:8ce494870ba6 | 11 | #define NEW 1 |
spinal | 13:8ce494870ba6 | 12 | #define RELEASE 2 |
spinal | 13:8ce494870ba6 | 13 | byte CompletePad, ExPad, TempPad, myPad; |
spinal | 13:8ce494870ba6 | 14 | bool _A[3], _B[3], _C[3], _Up[3], _Down[3], _Left[3], _Right[3]; |
spinal | 13:8ce494870ba6 | 15 | |
spinal | 13:8ce494870ba6 | 16 | DigitalIn _aPin(P1_9); |
spinal | 13:8ce494870ba6 | 17 | DigitalIn _bPin(P1_4); |
spinal | 13:8ce494870ba6 | 18 | DigitalIn _cPin(P1_10); |
spinal | 13:8ce494870ba6 | 19 | DigitalIn _upPin(P1_13); |
spinal | 13:8ce494870ba6 | 20 | DigitalIn _downPin(P1_3); |
spinal | 13:8ce494870ba6 | 21 | DigitalIn _leftPin(P1_25); |
spinal | 13:8ce494870ba6 | 22 | DigitalIn _rightPin(P1_7); |
spinal | 13:8ce494870ba6 | 23 | |
spinal | 13:8ce494870ba6 | 24 | void UPDATEPAD(int pad, int var) { |
spinal | 13:8ce494870ba6 | 25 | _C[pad] = (var >> 1)&1; |
spinal | 13:8ce494870ba6 | 26 | _B[pad] = (var >> 2)&1; |
spinal | 13:8ce494870ba6 | 27 | _A[pad] = (var >> 3)&1; |
spinal | 13:8ce494870ba6 | 28 | _Down[pad] = (var >> 4)&1; |
spinal | 13:8ce494870ba6 | 29 | _Left[pad] = (var >> 5)&1; |
spinal | 13:8ce494870ba6 | 30 | _Right[pad] = (var >> 6)&1; |
spinal | 13:8ce494870ba6 | 31 | _Up[pad] = (var >> 7)&1; |
spinal | 13:8ce494870ba6 | 32 | } |
spinal | 13:8ce494870ba6 | 33 | |
spinal | 13:8ce494870ba6 | 34 | void UpdatePad(int joy_code){ |
spinal | 13:8ce494870ba6 | 35 | ExPad = CompletePad; |
spinal | 13:8ce494870ba6 | 36 | CompletePad = joy_code; |
spinal | 13:8ce494870ba6 | 37 | UPDATEPAD(HELD, CompletePad); // held |
spinal | 13:8ce494870ba6 | 38 | UPDATEPAD(RELEASE, (ExPad & (~CompletePad))); // released |
spinal | 13:8ce494870ba6 | 39 | UPDATEPAD(NEW, (CompletePad & (~ExPad))); // newpress |
spinal | 13:8ce494870ba6 | 40 | } |
spinal | 12:37d999e445ad | 41 | |
spinal | 13:8ce494870ba6 | 42 | byte updateButtons(byte var){ |
spinal | 13:8ce494870ba6 | 43 | var = 0; |
spinal | 13:8ce494870ba6 | 44 | if (_cPin) var |= (1<<1); |
spinal | 13:8ce494870ba6 | 45 | if (_bPin) var |= (1<<2); |
spinal | 13:8ce494870ba6 | 46 | if (_aPin) var |= (1<<3); // P1_9 = A |
spinal | 13:8ce494870ba6 | 47 | if (_downPin) var |= (1<<4); |
spinal | 13:8ce494870ba6 | 48 | if (_leftPin) var |= (1<<5); |
spinal | 13:8ce494870ba6 | 49 | if (_rightPin) var |= (1<<6); |
spinal | 13:8ce494870ba6 | 50 | if (_upPin) var |= (1<<7); |
spinal | 13:8ce494870ba6 | 51 | |
spinal | 13:8ce494870ba6 | 52 | return var; |
spinal | 13:8ce494870ba6 | 53 | } |
spinal | 13:8ce494870ba6 | 54 | |
spinal | 12:37d999e445ad | 55 | |
spinal | 13:8ce494870ba6 | 56 | typedef struct{ |
spinal | 13:8ce494870ba6 | 57 | bool playSample; |
spinal | 13:8ce494870ba6 | 58 | int soundPoint; |
spinal | 13:8ce494870ba6 | 59 | const uint8_t *currentSound; |
spinal | 13:8ce494870ba6 | 60 | int currentSoundSize; |
spinal | 13:8ce494870ba6 | 61 | int volume; |
spinal | 13:8ce494870ba6 | 62 | int speed; |
spinal | 13:8ce494870ba6 | 63 | int repeat; |
spinal | 13:8ce494870ba6 | 64 | } sampletype; |
spinal | 13:8ce494870ba6 | 65 | |
spinal | 13:8ce494870ba6 | 66 | sampletype snd[4]; // up to 4 sounds at once? |
spinal | 13:8ce494870ba6 | 67 | int oldQuart; |
spinal | 13:8ce494870ba6 | 68 | |
spinal | 13:8ce494870ba6 | 69 | uint32_t nextBufferIndexToFill = 0; |
spinal | 13:8ce494870ba6 | 70 | uint32_t nextT = 0; |
spinal | 13:8ce494870ba6 | 71 | |
spinal | 13:8ce494870ba6 | 72 | int currentLine=0; |
spinal | 13:8ce494870ba6 | 73 | int mytick=0; |
spinal | 13:8ce494870ba6 | 74 | |
spinal | 13:8ce494870ba6 | 75 | |
spinal | 13:8ce494870ba6 | 76 | // note_speed << octave. = speed to play sample |
spinal | 13:8ce494870ba6 | 77 | |
spinal | 13:8ce494870ba6 | 78 | int note_speed[]={ 27,30,16,18,20,21,24, 29,0 ,17,19,0 ,23,25}; |
spinal | 13:8ce494870ba6 | 79 | // A B C D E F G A# B# C# D# E# F# G# |
spinal | 12:37d999e445ad | 80 | |
spinal | 11:a573cacdc078 | 81 | |
spinal | 13:8ce494870ba6 | 82 | void emptyBuffer(){ |
spinal | 13:8ce494870ba6 | 83 | for(int t=0; t<SBUFSIZE;){ |
spinal | 13:8ce494870ba6 | 84 | soundbuf[++t]=0; |
spinal | 13:8ce494870ba6 | 85 | } |
spinal | 13:8ce494870ba6 | 86 | |
spinal | 13:8ce494870ba6 | 87 | for(int t=0; t<4; t++){ |
spinal | 13:8ce494870ba6 | 88 | snd[t].playSample=0; |
spinal | 13:8ce494870ba6 | 89 | } |
spinal | 13:8ce494870ba6 | 90 | |
spinal | 13:8ce494870ba6 | 91 | } |
spinal | 13:8ce494870ba6 | 92 | |
spinal | 13:8ce494870ba6 | 93 | uint8_t playSound(int channel, const unsigned char *sound, uint16_t soundSize, int volume = 255, int speed=255, int repeat=0){ |
spinal | 12:37d999e445ad | 94 | /* |
spinal | 13:8ce494870ba6 | 95 | int channel=0; |
spinal | 13:8ce494870ba6 | 96 | for(int t=0; t<4; t++){ |
spinal | 13:8ce494870ba6 | 97 | if(snd[t].playSample==0){ |
spinal | 13:8ce494870ba6 | 98 | channel=t; |
spinal | 13:8ce494870ba6 | 99 | } |
spinal | 12:37d999e445ad | 100 | } |
spinal | 12:37d999e445ad | 101 | */ |
spinal | 13:8ce494870ba6 | 102 | snd[channel].currentSound = sound; |
spinal | 13:8ce494870ba6 | 103 | snd[channel].currentSoundSize = (soundSize*255)/speed; |
spinal | 13:8ce494870ba6 | 104 | snd[channel].soundPoint = 0; |
spinal | 13:8ce494870ba6 | 105 | snd[channel].playSample = 1; |
spinal | 13:8ce494870ba6 | 106 | snd[channel].volume = volume; |
spinal | 13:8ce494870ba6 | 107 | snd[channel].speed = speed; |
spinal | 13:8ce494870ba6 | 108 | snd[channel].repeat = repeat; |
spinal | 12:37d999e445ad | 109 | |
spinal | 13:8ce494870ba6 | 110 | return channel; |
spinal | 13:8ce494870ba6 | 111 | } |
spinal | 13:8ce494870ba6 | 112 | |
spinal | 13:8ce494870ba6 | 113 | uint8_t mixSound(int samplePos) |
spinal | 13:8ce494870ba6 | 114 | { |
spinal | 13:8ce494870ba6 | 115 | int temp = 0; |
spinal | 13:8ce494870ba6 | 116 | int ss[4]; |
spinal | 12:37d999e445ad | 117 | |
spinal | 13:8ce494870ba6 | 118 | for(int s=0; s<4; s++){ |
spinal | 13:8ce494870ba6 | 119 | ss[s] = (snd[s].currentSound[(snd[s].soundPoint*snd[s].speed)>>8]*snd[s].volume>>8) * snd[s].playSample; |
spinal | 13:8ce494870ba6 | 120 | ++snd[s].soundPoint; |
spinal | 13:8ce494870ba6 | 121 | if(snd[s].soundPoint >= snd[s].currentSoundSize){ |
spinal | 13:8ce494870ba6 | 122 | if(snd[s].repeat){ |
spinal | 13:8ce494870ba6 | 123 | snd[s].soundPoint=0; |
spinal | 13:8ce494870ba6 | 124 | }else{ |
spinal | 13:8ce494870ba6 | 125 | snd[s].playSample=0; |
spinal | 13:8ce494870ba6 | 126 | snd[s].soundPoint=0; |
spinal | 13:8ce494870ba6 | 127 | } |
spinal | 13:8ce494870ba6 | 128 | } |
spinal | 13:8ce494870ba6 | 129 | } |
spinal | 13:8ce494870ba6 | 130 | |
spinal | 11:a573cacdc078 | 131 | |
spinal | 13:8ce494870ba6 | 132 | // temp = (ss[0] + ss[1] + ss[2] + ss[3]) - (ss[0] * ss[1] * ss[2] * ss[3]); |
spinal | 13:8ce494870ba6 | 133 | temp = ((127 - ss[0] + ss[1] + ss[2] + ss[3])/4)+127; |
spinal | 13:8ce494870ba6 | 134 | |
spinal | 13:8ce494870ba6 | 135 | return temp; |
spinal | 13:8ce494870ba6 | 136 | } |
spinal | 13:8ce494870ba6 | 137 | |
spinal | 13:8ce494870ba6 | 138 | // Fills an audio buffer with the samples generated by the Bytebeat function |
spinal | 13:8ce494870ba6 | 139 | void generateBuffer(uint32_t bufferIndex, uint32_t nextT) { |
spinal | 13:8ce494870ba6 | 140 | |
spinal | 13:8ce494870ba6 | 141 | //bufferIndex = (currentBuffer + 2)&3; |
spinal | 13:8ce494870ba6 | 142 | |
spinal | 13:8ce494870ba6 | 143 | uint32_t index= 0; |
spinal | 13:8ce494870ba6 | 144 | for(uint32_t t=0; t<BUFFER_SIZE; t++,index++){ |
spinal | 13:8ce494870ba6 | 145 | uint8_t sample = mixSound(t); |
spinal | 13:8ce494870ba6 | 146 | buffers[bufferIndex][index] = sample; |
spinal | 12:37d999e445ad | 147 | } |
spinal | 12:37d999e445ad | 148 | |
spinal | 13:8ce494870ba6 | 149 | } |
spinal | 12:37d999e445ad | 150 | |
spinal | 12:37d999e445ad | 151 | |
spinal | 13:8ce494870ba6 | 152 | void updateSample(){ |
spinal | 13:8ce494870ba6 | 153 | |
spinal | 13:8ce494870ba6 | 154 | int quart = soundbufindex / 512; |
spinal | 13:8ce494870ba6 | 155 | int sndOffset[]={512,1024,1536,0}; |
spinal | 13:8ce494870ba6 | 156 | |
spinal | 13:8ce494870ba6 | 157 | if(oldQuart != quart){ |
spinal | 13:8ce494870ba6 | 158 | oldQuart = quart; |
spinal | 13:8ce494870ba6 | 159 | for(int t=0; t<SBUFSIZE/4;){ |
spinal | 13:8ce494870ba6 | 160 | uint8_t sample = mixSound(t); |
spinal | 13:8ce494870ba6 | 161 | soundbuf[t+sndOffset[quart]] = sample; |
spinal | 13:8ce494870ba6 | 162 | |
spinal | 13:8ce494870ba6 | 163 | for(int s=0; s<4; s++){ |
spinal | 13:8ce494870ba6 | 164 | ++snd[s].soundPoint; |
spinal | 13:8ce494870ba6 | 165 | if(snd[s].soundPoint >= snd[s].currentSoundSize){ |
spinal | 13:8ce494870ba6 | 166 | if(snd[s].repeat){ |
spinal | 13:8ce494870ba6 | 167 | snd[s].soundPoint=0; |
spinal | 13:8ce494870ba6 | 168 | }else{ |
spinal | 13:8ce494870ba6 | 169 | snd[s].playSample=0; |
spinal | 13:8ce494870ba6 | 170 | } |
spinal | 13:8ce494870ba6 | 171 | } |
spinal | 13:8ce494870ba6 | 172 | } |
spinal | 13:8ce494870ba6 | 173 | t++; |
spinal | 13:8ce494870ba6 | 174 | } |
spinal | 13:8ce494870ba6 | 175 | } |
spinal | 13:8ce494870ba6 | 176 | |
spinal | 13:8ce494870ba6 | 177 | } |
spinal | 13:8ce494870ba6 | 178 | |
spinal | 13:8ce494870ba6 | 179 | void update_tune(){ |
spinal | 12:37d999e445ad | 180 | |
spinal | 13:8ce494870ba6 | 181 | for(int t=0; t<4; t++){ |
spinal | 13:8ce494870ba6 | 182 | char note = tune[pattern][currentLine][t][0]; |
spinal | 13:8ce494870ba6 | 183 | char octave = tune[pattern][currentLine][t][1]; |
spinal | 13:8ce494870ba6 | 184 | char instrument = tune[pattern][currentLine][t][2]; |
spinal | 13:8ce494870ba6 | 185 | char volume = tune[pattern][currentLine][t][3] * 4; |
spinal | 13:8ce494870ba6 | 186 | |
spinal | 13:8ce494870ba6 | 187 | if(note > 0){ |
spinal | 13:8ce494870ba6 | 188 | |
spinal | 13:8ce494870ba6 | 189 | int speed = (note_speed[note-1] << octave); // >> 1 |
spinal | 13:8ce494870ba6 | 190 | |
spinal | 13:8ce494870ba6 | 191 | switch(instrument){ |
spinal | 13:8ce494870ba6 | 192 | case 1: |
spinal | 13:8ce494870ba6 | 193 | playSound(t, s_01, sizeof(s_01), volume, speed, sampleRepeat[0]); |
spinal | 13:8ce494870ba6 | 194 | break; |
spinal | 13:8ce494870ba6 | 195 | case 2: |
spinal | 13:8ce494870ba6 | 196 | playSound(t, s_02, sizeof(s_02), volume, speed, sampleRepeat[1]); |
spinal | 13:8ce494870ba6 | 197 | break; |
spinal | 13:8ce494870ba6 | 198 | case 3: |
spinal | 13:8ce494870ba6 | 199 | playSound(t, s_03, sizeof(s_03), volume, speed, sampleRepeat[2]); |
spinal | 13:8ce494870ba6 | 200 | break; |
spinal | 13:8ce494870ba6 | 201 | case 4: |
spinal | 13:8ce494870ba6 | 202 | playSound(t, s_04, sizeof(s_04), volume, speed, sampleRepeat[3]); |
spinal | 13:8ce494870ba6 | 203 | break; |
spinal | 13:8ce494870ba6 | 204 | } |
spinal | 13:8ce494870ba6 | 205 | } |
spinal | 13:8ce494870ba6 | 206 | |
spinal | 13:8ce494870ba6 | 207 | snd[t].volume = volume; |
spinal | 13:8ce494870ba6 | 208 | |
spinal | 13:8ce494870ba6 | 209 | } |
spinal | 13:8ce494870ba6 | 210 | |
spinal | 13:8ce494870ba6 | 211 | if(currentLine++==63){ |
spinal | 13:8ce494870ba6 | 212 | currentLine=0; |
spinal | 13:8ce494870ba6 | 213 | pattern++; |
spinal | 13:8ce494870ba6 | 214 | } |
spinal | 13:8ce494870ba6 | 215 | } |
spinal | 12:37d999e445ad | 216 | |
spinal | 12:37d999e445ad | 217 | |
spinal | 12:37d999e445ad | 218 | int main () |
spinal | 12:37d999e445ad | 219 | { |
spinal | 12:37d999e445ad | 220 | mygame.begin(); |
spinal | 13:8ce494870ba6 | 221 | mygame.setFrameRate(255); |
spinal | 13:8ce494870ba6 | 222 | // emptyBuffer(); // clear the sound buffer |
spinal | 12:37d999e445ad | 223 | |
spinal | 13:8ce494870ba6 | 224 | // The audio engine uses 4 buffers. Generate all 4 buffers ahead. |
spinal | 13:8ce494870ba6 | 225 | uint32_t nextT = 0; |
spinal | 13:8ce494870ba6 | 226 | generateBuffer(0, nextT); nextT += BUFFER_SIZE; |
spinal | 13:8ce494870ba6 | 227 | generateBuffer(1, nextT); nextT += BUFFER_SIZE; |
spinal | 13:8ce494870ba6 | 228 | generateBuffer(2, nextT); nextT += BUFFER_SIZE; |
spinal | 13:8ce494870ba6 | 229 | generateBuffer(3, nextT); nextT += BUFFER_SIZE; |
spinal | 12:37d999e445ad | 230 | |
spinal | 13:8ce494870ba6 | 231 | // Set global audio variables |
spinal | 13:8ce494870ba6 | 232 | currentBuffer = 0; |
spinal | 13:8ce494870ba6 | 233 | currentPtr = buffers[currentBuffer]; |
spinal | 13:8ce494870ba6 | 234 | endPtr = currentPtr + BUFFER_SIZE; |
spinal | 13:8ce494870ba6 | 235 | |
spinal | 13:8ce494870ba6 | 236 | // Init audio stream. |
spinal | 13:8ce494870ba6 | 237 | pokPlayStream(); // activate stream |
spinal | 13:8ce494870ba6 | 238 | mygame.sound.ampEnable(true); |
spinal | 13:8ce494870ba6 | 239 | mygame.sound.playMusicStream(); |
spinal | 13:8ce494870ba6 | 240 | |
spinal | 13:8ce494870ba6 | 241 | |
spinal | 13:8ce494870ba6 | 242 | uint32_t nextBufferIndexToFill = 0; |
spinal | 11:a573cacdc078 | 243 | |
spinal | 12:37d999e445ad | 244 | while (mygame.isRunning()) |
spinal | 12:37d999e445ad | 245 | { |
spinal | 13:8ce494870ba6 | 246 | // updateSample(); |
spinal | 13:8ce494870ba6 | 247 | |
spinal | 13:8ce494870ba6 | 248 | // Fill the next buffer if it is not used currently |
spinal | 13:8ce494870ba6 | 249 | if((uint32_t)currentBuffer != nextBufferIndexToFill) { |
spinal | 13:8ce494870ba6 | 250 | // Generate buffer |
spinal | 13:8ce494870ba6 | 251 | generateBuffer(nextBufferIndexToFill, nextT); |
spinal | 13:8ce494870ba6 | 252 | |
spinal | 13:8ce494870ba6 | 253 | if(++nextBufferIndexToFill > 3) |
spinal | 13:8ce494870ba6 | 254 | nextBufferIndexToFill = 0; |
spinal | 13:8ce494870ba6 | 255 | nextT += BUFFER_SIZE; |
spinal | 13:8ce494870ba6 | 256 | } |
spinal | 13:8ce494870ba6 | 257 | |
spinal | 13:8ce494870ba6 | 258 | if(++mytick==2){ |
spinal | 13:8ce494870ba6 | 259 | mytick=0; |
spinal | 13:8ce494870ba6 | 260 | |
spinal | 13:8ce494870ba6 | 261 | update_tune(); |
spinal | 13:8ce494870ba6 | 262 | } |
spinal | 13:8ce494870ba6 | 263 | |
spinal | 12:37d999e445ad | 264 | if (mygame.update()) |
spinal | 12:37d999e445ad | 265 | { |
spinal | 13:8ce494870ba6 | 266 | // update buttons |
spinal | 13:8ce494870ba6 | 267 | myPad = updateButtons(myPad); |
spinal | 13:8ce494870ba6 | 268 | UpdatePad(myPad); |
spinal | 12:37d999e445ad | 269 | |
spinal | 12:37d999e445ad | 270 | d.color = 1; |
spinal | 13:8ce494870ba6 | 271 | d.printf("Tick %d", mytick); |
spinal | 13:8ce494870ba6 | 272 | d.printf("Line %d", currentLine); |
spinal | 12:37d999e445ad | 273 | |
spinal | 12:37d999e445ad | 274 | } |
spinal | 12:37d999e445ad | 275 | } |
spinal | 11:a573cacdc078 | 276 | } |
spinal | 11:a573cacdc078 | 277 | |
spinal | 11:a573cacdc078 | 278 |