aaaaaaaaa

Dependencies:   mbed

Committer:
dicarloj
Date:
Sun Nov 10 23:19:38 2019 +0000
Revision:
0:6679ec22f0e5
aaaaaaaaaaaaaaa

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dicarloj 0:6679ec22f0e5 1 #include "player.h"
dicarloj 0:6679ec22f0e5 2
dicarloj 0:6679ec22f0e5 3 #include <string.h>
dicarloj 0:6679ec22f0e5 4 #include <math.h>
dicarloj 0:6679ec22f0e5 5 #include <stdlib.h>
dicarloj 0:6679ec22f0e5 6
dicarloj 0:6679ec22f0e5 7 Note* song = NULL;
dicarloj 0:6679ec22f0e5 8 uint32_t songLength = 0;
dicarloj 0:6679ec22f0e5 9
dicarloj 0:6679ec22f0e5 10
dicarloj 0:6679ec22f0e5 11 struct osc {
dicarloj 0:6679ec22f0e5 12 uint32_t duration_remaining;
dicarloj 0:6679ec22f0e5 13 uint16_t period;
dicarloj 0:6679ec22f0e5 14 uint16_t on_time;
dicarloj 0:6679ec22f0e5 15 };
dicarloj 0:6679ec22f0e5 16
dicarloj 0:6679ec22f0e5 17 static osc oscs[MAX_NOTES];
dicarloj 0:6679ec22f0e5 18 static osc* oscPool[MAX_NOTES];
dicarloj 0:6679ec22f0e5 19 static osc** oscPoolEnd;
dicarloj 0:6679ec22f0e5 20 static osc** oscPoolPtr;
dicarloj 0:6679ec22f0e5 21 static uint32_t now = 0;
dicarloj 0:6679ec22f0e5 22 static uint32_t songPosition = 0;
dicarloj 0:6679ec22f0e5 23 bool songDone = false;
dicarloj 0:6679ec22f0e5 24 static uint32_t nextNoteTick = 0;
dicarloj 0:6679ec22f0e5 25 static uint16_t frequencyTable[256];
dicarloj 0:6679ec22f0e5 26 static uint16_t periodTable[256];
dicarloj 0:6679ec22f0e5 27 static uint8_t nPlaying = 0;
dicarloj 0:6679ec22f0e5 28
dicarloj 0:6679ec22f0e5 29 void initialize_play() {
dicarloj 0:6679ec22f0e5 30 memset((void*)oscs,0,MAX_NOTES*sizeof(osc));
dicarloj 0:6679ec22f0e5 31 now = 0;
dicarloj 0:6679ec22f0e5 32 songPosition = 0;
dicarloj 0:6679ec22f0e5 33 songDone = false;
dicarloj 0:6679ec22f0e5 34 nextNoteTick = song[0]._start_tick;
dicarloj 0:6679ec22f0e5 35 nPlaying = 0;
dicarloj 0:6679ec22f0e5 36 for(int i = 0; i < 256; i++)
dicarloj 0:6679ec22f0e5 37 {
dicarloj 0:6679ec22f0e5 38 float offset = 69;
dicarloj 0:6679ec22f0e5 39 float f = 440.f * pow(2.f, (i - offset)/12.0f);
dicarloj 0:6679ec22f0e5 40 float f2 = ((float)SAMPLE_FREQEUENCY) / f;
dicarloj 0:6679ec22f0e5 41 frequencyTable[i] = 440*pow(2,(i - offset)/12.0f);
dicarloj 0:6679ec22f0e5 42 periodTable[i] = ((uint32_t)f2) > 1 ? f2 : 1;
dicarloj 0:6679ec22f0e5 43 //printf("period %d %d (%d Hz)\n", i, periodTable[i],frequencyTable[i]);
dicarloj 0:6679ec22f0e5 44 }
dicarloj 0:6679ec22f0e5 45 printf("Done initialize\n");
dicarloj 0:6679ec22f0e5 46
dicarloj 0:6679ec22f0e5 47 for(int i = 0; i < MAX_NOTES; i++) {
dicarloj 0:6679ec22f0e5 48 oscPool[i] = oscs + i;
dicarloj 0:6679ec22f0e5 49 }
dicarloj 0:6679ec22f0e5 50 oscPoolEnd = oscPool + MAX_NOTES;
dicarloj 0:6679ec22f0e5 51 oscPoolPtr = oscPool;
dicarloj 0:6679ec22f0e5 52 }
dicarloj 0:6679ec22f0e5 53
dicarloj 0:6679ec22f0e5 54
dicarloj 0:6679ec22f0e5 55 uint16_t play() {
dicarloj 0:6679ec22f0e5 56 if(songDone) return 0;
dicarloj 0:6679ec22f0e5 57 uint16_t isOn = 0;
dicarloj 0:6679ec22f0e5 58
dicarloj 0:6679ec22f0e5 59 // play/end notes
dicarloj 0:6679ec22f0e5 60 for(uint8_t i = 0; i < MAX_NOTES; i++) {
dicarloj 0:6679ec22f0e5 61 osc* o = oscs + i;
dicarloj 0:6679ec22f0e5 62 if(!o->duration_remaining) continue;
dicarloj 0:6679ec22f0e5 63
dicarloj 0:6679ec22f0e5 64 // note is playing
dicarloj 0:6679ec22f0e5 65 uint16_t progress = now % o->period;
dicarloj 0:6679ec22f0e5 66 uint16_t effectiveOnTime = o->on_time / nPlaying;
dicarloj 0:6679ec22f0e5 67
dicarloj 0:6679ec22f0e5 68 if(progress < effectiveOnTime) {
dicarloj 0:6679ec22f0e5 69 isOn += 1;
dicarloj 0:6679ec22f0e5 70 }
dicarloj 0:6679ec22f0e5 71
dicarloj 0:6679ec22f0e5 72 if(o->duration_remaining == 1) {
dicarloj 0:6679ec22f0e5 73 nPlaying--;
dicarloj 0:6679ec22f0e5 74 *(--oscPoolPtr) = o;
dicarloj 0:6679ec22f0e5 75 }
dicarloj 0:6679ec22f0e5 76 o->duration_remaining--;
dicarloj 0:6679ec22f0e5 77 }
dicarloj 0:6679ec22f0e5 78
dicarloj 0:6679ec22f0e5 79 // avoids mod.
dicarloj 0:6679ec22f0e5 80 if(!(now & (1 << CHEATER_FREQUENCY_MULT_POWER))) {
dicarloj 0:6679ec22f0e5 81 // is there a new note?
dicarloj 0:6679ec22f0e5 82 if(nextNoteTick <= (now >> CHEATER_FREQUENCY_MULT_POWER) && oscPoolPtr < oscPoolEnd) {
dicarloj 0:6679ec22f0e5 83 // there is note to load right now, find an oscillator
dicarloj 0:6679ec22f0e5 84 osc* o = *(oscPoolPtr++);
dicarloj 0:6679ec22f0e5 85
dicarloj 0:6679ec22f0e5 86 if(!o) {
dicarloj 0:6679ec22f0e5 87 printf("Too many notes! skipping...\n");
dicarloj 0:6679ec22f0e5 88 } else {
dicarloj 0:6679ec22f0e5 89 Note* note = song + songPosition;
dicarloj 0:6679ec22f0e5 90 o->duration_remaining = ((uint32_t)note->_duration) << CHEATER_FREQUENCY_MULT_POWER;
dicarloj 0:6679ec22f0e5 91 o->period = periodTable[note->_note];
dicarloj 0:6679ec22f0e5 92 o->on_time = 5 + o->period / 20;
dicarloj 0:6679ec22f0e5 93 nPlaying++;
dicarloj 0:6679ec22f0e5 94 }
dicarloj 0:6679ec22f0e5 95
dicarloj 0:6679ec22f0e5 96 // prepare for next note
dicarloj 0:6679ec22f0e5 97 songPosition++;
dicarloj 0:6679ec22f0e5 98 if(songPosition >= songLength) songDone = true;
dicarloj 0:6679ec22f0e5 99 nextNoteTick = song[songPosition]._start_tick;
dicarloj 0:6679ec22f0e5 100 }
dicarloj 0:6679ec22f0e5 101 }
dicarloj 0:6679ec22f0e5 102
dicarloj 0:6679ec22f0e5 103
dicarloj 0:6679ec22f0e5 104 now++;
dicarloj 0:6679ec22f0e5 105 return isOn;
dicarloj 0:6679ec22f0e5 106 }