#include "GameAudio.h"
#include <cstring>
GameAudioRenderer::GameAudioRenderer() : AudioRenderer()
{
// TODO: re-enable later. Just while testing memory usage and performance, temp disable
//mp3.open("music.mp3");
//initSemiToneFrequencies();
// const char* twinkleTwinkleCh1 = " C C C C C C C C C C C C C C ";
// const char* twinkleTwinkleCh2 = "E---- AABABACDDDDB--B--A-- BA";
const char* twinkleTwinkleCh1 = "CCGGAAG- FFEEDDC- GGFFEED-- GGFFEED- CCGGAAG- FFEEDDC--- ";
const char* twinkleTwinkleCh2 = "CCGGAAG- FFEEDDC- GGFFEED-- GGFFEED- CCGGAAG- FFEEDDC--- ";
// const char* twinkleTwinkleCh2 = "C- G- F- AG- C--- ";
// const char* twinkleTwinkleCh2 = " ";
//const char* twinkleTwinkleCh1 = "C-C- G-G- AAG-- F-F- E-E- DDC- GG FF EE D-- GG FF EE D-- CCGG AA G- FFEE DD C--- ";
//const char* twinkleTwinkleCh2 = "C- G-- F- A G- C--- ";
m_tuneCh1 = twinkleTwinkleCh1;
m_tuneCh2 = twinkleTwinkleCh2;
}
void GameAudioRenderer::processMelodyChannel(size_t a_frameCount, uint16_t* a_outputBuffer, const char* a_tune, int& a_time, float a_octave, bool a_lerp)
{
int period = 0;
int volume = 50;
int tempo = 8000;//20000;
int accent = 3000;
float octave = a_octave; // C4
// A, B, C etc.
float frequencies[] = { 44100.0/440.00, 44100.0/246.94, 44100.0/261.63, 44100.0/293.66, 44100.0/329.63, 44100.0/349.23, 44100.0/392.00, 44100.0/440.00 };
int noteOff = (m_sample / tempo) % strlen(a_tune);
char note = a_tune[noteOff];
if ((m_sample % tempo) < accent && note != '-')
volume = (m_sample % tempo) / (accent / 50);
if (note == '-')
{
while (note == '-')
note = a_tune[noteOff--];
noteOff--; // for virbreto effect when lerping
}
static int lastVol = 0;
if (note >= 'A' && note <= 'G')
period = frequencies[note - 'A'] / octave;// * 4;
else {
lastVol = 0;
return; // nothing to play
}
if (a_lerp)
{
noteOff++;
char nextNote = a_tune[noteOff];
if (nextNote >= 'A' && nextNote <= 'G')
{
float ratioToNextNote = float(m_sample % tempo) / float(tempo);
int lerpToPeriod = frequencies[nextNote - 'A'] / octave;// * 4;
period = int((1.0-ratioToNextNote)*period + (ratioToNextNote)*lerpToPeriod); // mix
}
}
// Generate 1000 time units of square wave
size_t length = a_frameCount;
size_t off = 0;
while (a_time < length)
{
//static
int s_rem = 0;
for (int i = 0; i < s_rem; i++, off++)
if (off < a_frameCount)
a_outputBuffer[off] = (sign * lastVol) * 256;
sign = -sign;
lastVol = volume;
for (int i = 0; i < period; i++, off++)
if (off < a_frameCount)
a_outputBuffer[off] = (sign * volume) * 256;
else {
//s_rem = period - i;
break;
}
//off += period;
a_time += period;
}
a_time -= length; // adjust time to new frame
}
void GameAudioRenderer::renderSamples(void* a_outputBuffer, size_t a_frameCount)
{
mp3.renderSamples(a_outputBuffer, a_frameCount);
/*
processMelodyChannel(a_frameCount, (uint16_t*)a_outputBuffer, m_tuneCh1, timeCh1, 1.0, false);
timeCh2 += 100;
//processMelodyChannel(a_frameCount, a_outputBuffer, m_tuneCh2, timeCh2, 2.0, true);
timeCh2 -= 100;
m_sample += a_frameCount;
*/
}