![](/media/cache/profiles/916954106a13204fa4909ae2d48e0602.jpg.50x50_q85.jpg)
aaaaaaaaa
player.cpp
- Committer:
- dicarloj
- Date:
- 2019-11-10
- Revision:
- 0:6679ec22f0e5
File content as of revision 0:6679ec22f0e5:
#include "player.h" #include <string.h> #include <math.h> #include <stdlib.h> Note* song = NULL; uint32_t songLength = 0; struct osc { uint32_t duration_remaining; uint16_t period; uint16_t on_time; }; static osc oscs[MAX_NOTES]; static osc* oscPool[MAX_NOTES]; static osc** oscPoolEnd; static osc** oscPoolPtr; static uint32_t now = 0; static uint32_t songPosition = 0; bool songDone = false; static uint32_t nextNoteTick = 0; static uint16_t frequencyTable[256]; static uint16_t periodTable[256]; static uint8_t nPlaying = 0; void initialize_play() { memset((void*)oscs,0,MAX_NOTES*sizeof(osc)); now = 0; songPosition = 0; songDone = false; nextNoteTick = song[0]._start_tick; nPlaying = 0; for(int i = 0; i < 256; i++) { float offset = 69; float f = 440.f * pow(2.f, (i - offset)/12.0f); float f2 = ((float)SAMPLE_FREQEUENCY) / f; frequencyTable[i] = 440*pow(2,(i - offset)/12.0f); periodTable[i] = ((uint32_t)f2) > 1 ? f2 : 1; //printf("period %d %d (%d Hz)\n", i, periodTable[i],frequencyTable[i]); } printf("Done initialize\n"); for(int i = 0; i < MAX_NOTES; i++) { oscPool[i] = oscs + i; } oscPoolEnd = oscPool + MAX_NOTES; oscPoolPtr = oscPool; } uint16_t play() { if(songDone) return 0; uint16_t isOn = 0; // play/end notes for(uint8_t i = 0; i < MAX_NOTES; i++) { osc* o = oscs + i; if(!o->duration_remaining) continue; // note is playing uint16_t progress = now % o->period; uint16_t effectiveOnTime = o->on_time / nPlaying; if(progress < effectiveOnTime) { isOn += 1; } if(o->duration_remaining == 1) { nPlaying--; *(--oscPoolPtr) = o; } o->duration_remaining--; } // avoids mod. if(!(now & (1 << CHEATER_FREQUENCY_MULT_POWER))) { // is there a new note? if(nextNoteTick <= (now >> CHEATER_FREQUENCY_MULT_POWER) && oscPoolPtr < oscPoolEnd) { // there is note to load right now, find an oscillator osc* o = *(oscPoolPtr++); if(!o) { printf("Too many notes! skipping...\n"); } else { Note* note = song + songPosition; o->duration_remaining = ((uint32_t)note->_duration) << CHEATER_FREQUENCY_MULT_POWER; o->period = periodTable[note->_note]; o->on_time = 5 + o->period / 20; nPlaying++; } // prepare for next note songPosition++; if(songPosition >= songLength) songDone = true; nextNoteTick = song[songPosition]._start_tick; } } now++; return isOn; }