![](/media/cache/profiles/916954106a13204fa4909ae2d48e0602.jpg.50x50_q85.jpg)
aaaaaaaaa
Diff: player.cpp
- Revision:
- 0:6679ec22f0e5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/player.cpp Sun Nov 10 23:19:38 2019 +0000 @@ -0,0 +1,106 @@ +#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; +}