attempt at tracker style music
main.cpp
- Committer:
- spinal
- Date:
- 2018-11-17
- Revision:
- 13:8ce494870ba6
- Parent:
- 12:37d999e445ad
- Child:
- 14:97a5deea7c94
- Child:
- 15:209481812170
File content as of revision 13:8ce494870ba6:
#include "Pokitto.h" #include "HWSound.h" #include "snd.h" #include "tune.h" Pokitto::Core mygame; Pokitto::Display d; //------------------------[ Button handling, very accurate ]------------------------ #define HELD 0 #define NEW 1 #define RELEASE 2 byte CompletePad, ExPad, TempPad, myPad; bool _A[3], _B[3], _C[3], _Up[3], _Down[3], _Left[3], _Right[3]; DigitalIn _aPin(P1_9); DigitalIn _bPin(P1_4); DigitalIn _cPin(P1_10); DigitalIn _upPin(P1_13); DigitalIn _downPin(P1_3); DigitalIn _leftPin(P1_25); DigitalIn _rightPin(P1_7); void UPDATEPAD(int pad, int var) { _C[pad] = (var >> 1)&1; _B[pad] = (var >> 2)&1; _A[pad] = (var >> 3)&1; _Down[pad] = (var >> 4)&1; _Left[pad] = (var >> 5)&1; _Right[pad] = (var >> 6)&1; _Up[pad] = (var >> 7)&1; } void UpdatePad(int joy_code){ ExPad = CompletePad; CompletePad = joy_code; UPDATEPAD(HELD, CompletePad); // held UPDATEPAD(RELEASE, (ExPad & (~CompletePad))); // released UPDATEPAD(NEW, (CompletePad & (~ExPad))); // newpress } byte updateButtons(byte var){ var = 0; if (_cPin) var |= (1<<1); if (_bPin) var |= (1<<2); if (_aPin) var |= (1<<3); // P1_9 = A if (_downPin) var |= (1<<4); if (_leftPin) var |= (1<<5); if (_rightPin) var |= (1<<6); if (_upPin) var |= (1<<7); return var; } typedef struct{ bool playSample; int soundPoint; const uint8_t *currentSound; int 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; int currentLine=0; int mytick=0; // note_speed << octave. = speed to play sample int note_speed[]={ 27,30,16,18,20,21,24, 29,0 ,17,19,0 ,23,25}; // A B C D E F G A# B# C# D# E# F# G# void emptyBuffer(){ for(int t=0; t<SBUFSIZE;){ soundbuf[++t]=0; } for(int t=0; t<4; t++){ snd[t].playSample=0; } } uint8_t playSound(int channel, const unsigned char *sound, uint16_t soundSize, int volume = 255, int speed=255, int repeat=0){ /* int channel=0; for(int t=0; t<4; t++){ if(snd[t].playSample==0){ channel=t; } } */ snd[channel].currentSound = sound; snd[channel].currentSoundSize = (soundSize*255)/speed; snd[channel].soundPoint = 0; snd[channel].playSample = 1; snd[channel].volume = volume; snd[channel].speed = speed; snd[channel].repeat = repeat; return channel; } uint8_t mixSound(int samplePos) { int temp = 0; int ss[4]; for(int s=0; s<4; s++){ ss[s] = (snd[s].currentSound[(snd[s].soundPoint*snd[s].speed)>>8]*snd[s].volume>>8) * snd[s].playSample; ++snd[s].soundPoint; if(snd[s].soundPoint >= 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]) - (ss[0] * ss[1] * ss[2] * ss[3]); temp = ((127 - ss[0] + ss[1] + ss[2] + ss[3])/4)+127; return temp; } // Fills an audio buffer with the samples generated by the Bytebeat function void generateBuffer(uint32_t bufferIndex, uint32_t nextT) { //bufferIndex = (currentBuffer + 2)&3; uint32_t index= 0; for(uint32_t t=0; t<BUFFER_SIZE; t++,index++){ uint8_t sample = mixSound(t); buffers[bufferIndex][index] = sample; } } void updateSample(){ int quart = soundbufindex / 512; int sndOffset[]={512,1024,1536,0}; if(oldQuart != quart){ oldQuart = quart; for(int t=0; t<SBUFSIZE/4;){ uint8_t sample = mixSound(t); soundbuf[t+sndOffset[quart]] = sample; for(int s=0; s<4; s++){ ++snd[s].soundPoint; if(snd[s].soundPoint >= snd[s].currentSoundSize){ if(snd[s].repeat){ snd[s].soundPoint=0; }else{ snd[s].playSample=0; } } } t++; } } } void update_tune(){ for(int t=0; t<4; t++){ char note = tune[pattern][currentLine][t][0]; char octave = tune[pattern][currentLine][t][1]; char instrument = tune[pattern][currentLine][t][2]; char volume = tune[pattern][currentLine][t][3] * 4; if(note > 0){ int speed = (note_speed[note-1] << octave); // >> 1 switch(instrument){ case 1: playSound(t, s_01, sizeof(s_01), volume, speed, sampleRepeat[0]); break; case 2: playSound(t, s_02, sizeof(s_02), volume, speed, sampleRepeat[1]); break; case 3: playSound(t, s_03, sizeof(s_03), volume, speed, sampleRepeat[2]); break; case 4: playSound(t, s_04, sizeof(s_04), volume, speed, sampleRepeat[3]); break; } } snd[t].volume = volume; } if(currentLine++==63){ currentLine=0; pattern++; } } int main () { mygame.begin(); mygame.setFrameRate(255); // emptyBuffer(); // clear the sound buffer // The audio engine uses 4 buffers. Generate all 4 buffers ahead. uint32_t nextT = 0; generateBuffer(0, nextT); nextT += BUFFER_SIZE; generateBuffer(1, nextT); nextT += BUFFER_SIZE; generateBuffer(2, nextT); nextT += BUFFER_SIZE; generateBuffer(3, nextT); nextT += BUFFER_SIZE; // Set global audio variables currentBuffer = 0; currentPtr = buffers[currentBuffer]; endPtr = currentPtr + BUFFER_SIZE; // Init audio stream. pokPlayStream(); // activate stream mygame.sound.ampEnable(true); mygame.sound.playMusicStream(); uint32_t nextBufferIndexToFill = 0; while (mygame.isRunning()) { // updateSample(); // Fill the next buffer if it is not used currently if((uint32_t)currentBuffer != nextBufferIndexToFill) { // Generate buffer generateBuffer(nextBufferIndexToFill, nextT); if(++nextBufferIndexToFill > 3) nextBufferIndexToFill = 0; nextT += BUFFER_SIZE; } if(++mytick==2){ mytick=0; update_tune(); } if (mygame.update()) { // update buttons myPad = updateButtons(myPad); UpdatePad(myPad); d.color = 1; d.printf("Tick %d", mytick); d.printf("Line %d", currentLine); } } }