|
|
|
@@ -9,26 +9,69 @@ const float periods[108] = { 1348.49207, 1272.80688, 1201.37, 1133.94214, 1070.2
|
|
|
|
|
static float default_length = 0.25f;
|
|
|
|
|
static uint8_t volume = 64;
|
|
|
|
|
static uint8_t octave = 4;
|
|
|
|
|
static uint32_t tempo = 44100;
|
|
|
|
|
static uint32_t tempo = tempos[4]*10;
|
|
|
|
|
static uint8_t wave_type = 0;
|
|
|
|
|
static char* song_ptr = NULL;
|
|
|
|
|
static char* song = NULL;
|
|
|
|
|
static char song[256];
|
|
|
|
|
|
|
|
|
|
uint8_t generate_square_wave(unsigned int i, uint16_t period, uint8_t volume) {
|
|
|
|
|
return ( (i % period) < (period >> 1) ? volume : -volume );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t generate_saw_wave(unsigned int i, uint16_t period, uint8_t volume) {
|
|
|
|
|
uint16_t t = i % period;
|
|
|
|
|
|
|
|
|
|
// Mapea t (0..period-1) a un rango lineal -volume..+volume
|
|
|
|
|
int16_t v = -volume + (2 * volume * t) / period;
|
|
|
|
|
|
|
|
|
|
return (int8_t)v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t generate_triangle_wave(unsigned int i, uint16_t period, uint8_t volume) {
|
|
|
|
|
uint16_t t = i % period;
|
|
|
|
|
int16_t v = (t < period/2)
|
|
|
|
|
? (-volume + (2 * volume * t) / (period/2))
|
|
|
|
|
: ( volume - (2 * volume * (t - period/2)) / (period/2));
|
|
|
|
|
return (int8_t)v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t generate_periodic_noise(unsigned int i, uint16_t period, uint8_t volume) {
|
|
|
|
|
static int8_t current = 0;
|
|
|
|
|
|
|
|
|
|
if (i % period == 0) {
|
|
|
|
|
current = (rand() % (2 * volume + 1)) - volume;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return current;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t generate_wave(unsigned int i, uint16_t period, uint8_t volume) {
|
|
|
|
|
switch (wave_type) {
|
|
|
|
|
case 1: return generate_saw_wave(i, period, volume);
|
|
|
|
|
case 2: return generate_periodic_noise(i, period, volume);
|
|
|
|
|
default:return generate_square_wave(i, period, volume);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t interpret_note(uint8_t* buffer, const char note, const char param ) {
|
|
|
|
|
const uint32_t length = ( param == -1 ? default_length : ((float)lengths[uint8_t(param)])/10000.0f ) * tempo;
|
|
|
|
|
if( note == 100 ) { memset( buffer, 0, length ); return length; }
|
|
|
|
|
const uint16_t period = periods[note + octave*12];
|
|
|
|
|
|
|
|
|
|
for( unsigned int i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 1) ? volume : -volume );
|
|
|
|
|
for( unsigned int i = 0; i < length; i++ ) buffer[i] = generate_wave(i, period, volume);
|
|
|
|
|
return length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void play_init(const char* new_song) {
|
|
|
|
|
default_length = 0.25f;
|
|
|
|
|
volume=64;
|
|
|
|
|
octave=4;
|
|
|
|
|
tempo=44100;
|
|
|
|
|
if (song != NULL) free(song);
|
|
|
|
|
song = (char*)malloc( strlen( new_song ) + 1 );
|
|
|
|
|
strcpy( song, new_song );
|
|
|
|
|
tempo=tempos[4]*10;
|
|
|
|
|
wave_type = 0;
|
|
|
|
|
|
|
|
|
|
int len = strlen( new_song ) + 1;
|
|
|
|
|
if (len > 256) len = 256;
|
|
|
|
|
strncpy(song, new_song, len);
|
|
|
|
|
song_ptr = song;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -75,6 +118,10 @@ int32_t interpret_next_token(uint8_t* buffer) {
|
|
|
|
|
param = *++*token;
|
|
|
|
|
if( param >= 48 && param <= 57 ) { tempo = tempos[param - 48] * 10; ++*token; }
|
|
|
|
|
return 0;
|
|
|
|
|
case 'w':
|
|
|
|
|
param = *++*token;
|
|
|
|
|
if( param >= 48 && param <= 50 ) { wave_type = param - 48; ++*token; }
|
|
|
|
|
return 0;
|
|
|
|
|
case '\0':
|
|
|
|
|
return -1;
|
|
|
|
|
default:
|
|
|
|
|