- [WIP] Implementing instruments (envelopes) for Chirping
This commit is contained in:
42
chirp.cpp
42
chirp.cpp
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user