attempt at tracker style music

Dependencies:   PokittoLib

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?

UserRevisionLine numberNew 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