- [WIP] Implementing instruments (envelopes) for Chirping

This commit is contained in:
2023-01-10 20:03:52 +01:00
parent 256f4a2d04
commit e388d046b2

View File

@@ -13,7 +13,7 @@
#define MAX_CHANNELS 5 #define MAX_CHANNELS 5
typedef void (*waveform_t)(const uint16_t, const uint32_t, uint8_t*, const uint8_t); typedef void (*waveform_t)(const uint16_t, const uint32_t, const uint8_t); //, uint8_t*, const uint8_t);
static waveform_t waveforms[6]; static waveform_t waveforms[6];
const static uint16_t lengths[10] = { 313, 625, 938, 1250, 1875, 2500, 3750, 5000, 7500, 10000 }; const static uint16_t lengths[10] = { 313, 625, 938, 1250, 1875, 2500, 3750, 5000, 7500, 10000 };
@@ -23,9 +23,16 @@ const float periods[108] = { 1348.49207, 1272.80688, 1201.37, 1133.94214, 1070.2
SDL_AudioDeviceID audio_device; SDL_AudioDeviceID audio_device;
uint8_t audio_state = AUDIO_NONE; uint8_t audio_state = AUDIO_NONE;
struct instrument_t {
uint8_t waveform = 0;
int8_t volume[8] = {0,0,0,0,0,0,0,0};
int8_t pitch[8] = {0,0,0,0,0,0,0,0};
};
struct channel_t { struct channel_t {
char* song = NULL; char* song = NULL;
char* song_ptr = NULL; char* song_ptr = NULL;
uint32_t count = 0;
float length = 0.25f; float length = 0.25f;
uint8_t volume = 32; uint8_t volume = 32;
uint8_t octave = 4; uint8_t octave = 4;
@@ -37,6 +44,7 @@ struct channel_t {
char* stack[10] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; char* stack[10] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
uint8_t stackpos = 0; uint8_t stackpos = 0;
char* labels[10] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; char* labels[10] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
instrument_t instruments[5];
}; };
static channel_t channels[MAX_CHANNELS]; static channel_t channels[MAX_CHANNELS];
@@ -80,31 +88,33 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
} }
} }
void square_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) { #define COUNT (channels[c].count++ % period)
for( uint32_t i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 1) ? volume : -volume );
void square_waveform(const uint16_t period, const uint32_t length, const uint8_t c) {
for( uint32_t i = 0; i < length; i++ ) channels[c].play_buffer[i] = ( COUNT < (period >> 1) ? channels[c].volume : -channels[c].volume );
} }
void saw_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) { void saw_waveform(const uint16_t period, const uint32_t length, const uint8_t c) {
for( uint32_t i = 0; i < length; i++ ) buffer[i] = -volume + uint16_t( float(i % period) / float(period) * volume*2 ); for( uint32_t i = 0; i < length; i++ ) channels[c].play_buffer[i] = -channels[c].volume + uint16_t( float(COUNT) / float(period) * channels[c].volume*2 );
} }
void triangle_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) { void triangle_waveform(const uint16_t period, const uint32_t length, const uint8_t c) {
for( uint32_t i = 0; i < length; i++ ) { for( uint32_t i = 0; i < length; i++ ) {
uint16_t pos = i % period; uint16_t pos = COUNT;
uint16_t half_period = period >> 1; uint16_t half_period = period >> 1;
if (pos < half_period) { if (pos < half_period) {
buffer[i] = -volume + uint16_t( (float(pos) / float(half_period)) * float(volume*2) ); channels[c].play_buffer[i] = -channels[c].volume + uint16_t( (float(pos) / float(half_period)) * float(channels[c].volume*2) );
} else { } else {
buffer[i] = volume - uint16_t( (float(pos-half_period) / float(half_period)) * float(volume*2) ); channels[c].play_buffer[i] = channels[c].volume - uint16_t( (float(pos-half_period) / float(half_period)) * float(channels[c].volume*2) );
} }
} }
} }
void pulse12_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) { void pulse12_waveform(const uint16_t period, const uint32_t length, const uint8_t c) {
for( uint32_t i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 3) ? volume : -volume ); for( uint32_t i = 0; i < length; i++ ) channels[c].play_buffer[i] = ( COUNT < (period >> 3) ? channels[c].volume : -channels[c].volume );
} }
void pulse25_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) { void pulse25_waveform(const uint16_t period, const uint32_t length, const uint8_t c) {
for( uint32_t i = 0; i < length; i++ ) buffer[i] = ( (i % period) < (period >> 2) ? volume : -volume ); for( uint32_t i = 0; i < length; i++ ) channels[c].play_buffer[i] = ( COUNT < (period >> 2) ? channels[c].volume : -channels[c].volume );
} }
void pulse75_waveform(const uint16_t period, const uint32_t length, uint8_t *buffer, const uint8_t volume) { void pulse75_waveform(const uint16_t period, const uint32_t length, const uint8_t c) {
for( uint32_t i = 0; i < length; i++ ) buffer[i] = ( (i % period) < uint16_t(period-(period >> 2)) ? volume : -volume ); for( uint32_t i = 0; i < length; i++ ) channels[c].play_buffer[i] = ( COUNT < uint16_t(period-(period >> 2)) ? channels[c].volume : -channels[c].volume );
} }
void chirp_init() { void chirp_init() {
@@ -126,7 +136,7 @@ uint32_t interpret_note(const int c, const uint8_t note, const char param ) {
if( note == NOISE ) { for( uint32_t i = 0; i < length; i++ ) channels[c].play_buffer[i] = rand()%2==0 ? channels[c].volume : -channels[c].volume; return length; } if( note == NOISE ) { for( uint32_t i = 0; i < length; i++ ) channels[c].play_buffer[i] = rand()%2==0 ? channels[c].volume : -channels[c].volume; return length; }
const uint16_t period = periods[note + channels[c].octave*12]; const uint16_t period = periods[note + channels[c].octave*12];
waveforms[channels[c].waveform](period, length, channels[c].play_buffer, channels[c].volume); waveforms[channels[c].waveform](period, length, c); //channels[c].play_buffer, channels[c].volume);
return length; return length;
} }