pentabug/firmware/synth.c

82 lines
1.1 KiB
C
Raw Normal View History

2012-08-06 02:52:03 +02:00
#include <inttypes.h>
// sample rate is 8M / (3 * 64)
enum {
2012-08-06 03:35:28 +02:00
synth_channel_count = 2,
2012-08-06 02:52:03 +02:00
};
2012-08-06 03:35:28 +02:00
enum {
WAVE_PULSE,
WAVE_SAW,
};
2012-08-06 02:52:03 +02:00
typedef struct {
2012-08-06 03:35:28 +02:00
uint8_t wave;
2012-08-06 02:52:03 +02:00
uint16_t phase;
uint16_t speed;
2012-08-06 03:35:28 +02:00
uint32_t pulse_width;
uint8_t pulse_sweep;
uint8_t level; // envelop level
2012-08-06 02:52:03 +02:00
} synth_channel_t;
typedef struct {
synth_channel_t channels[synth_channel_count];
} synth_t;
static synth_t synth;
2012-08-06 03:35:28 +02:00
2012-08-06 02:52:03 +02:00
void synth_init(void)
{
// some test values
2012-08-06 03:35:28 +02:00
synth.channels[0].wave = WAVE_PULSE;
2012-08-06 02:52:03 +02:00
synth.channels[0].speed = 1153;
2012-08-06 03:35:28 +02:00
synth.channels[0].pulse_sweep = 0;
synth.channels[0].pulse_width = 1 << 31;
2012-08-06 02:52:03 +02:00
2012-08-06 03:35:28 +02:00
synth.channels[1].wave = WAVE_SAW;
2012-08-06 02:52:03 +02:00
synth.channels[1].speed = 1728;
2012-08-06 03:35:28 +02:00
2012-08-06 02:52:03 +02:00
}
uint16_t synth_mix(void)
{
uint16_t output = 0;
2012-08-06 03:35:28 +02:00
for(int i = 0; i < synth_channel_count; i++) {
2012-08-06 02:52:03 +02:00
synth_channel_t *chan = &synth.channels[i];
2012-08-06 03:35:28 +02:00
2012-08-06 02:52:03 +02:00
chan->phase += chan->speed;
2012-08-06 03:35:28 +02:00
chan->pulse_width += chan->pulse_sweep << 8;
uint8_t amp;
switch(chan->wave) {
case WAVE_PULSE:
amp = -(chan->phase < (chan->pulse_width >> 16));
break;
case WAVE_SAW:
amp = (chan->phase >> 8);
break;
default:
amp = 0;
break;
}
output += (amp & 0xff) / 2;
2012-08-06 02:52:03 +02:00
}
return output;
}