From 65ea2847dd6802cd7a233ea1ea2f1ec2bf2ae8d7 Mon Sep 17 00:00:00 2001 From: bigalex Date: Tue, 7 Aug 2012 20:03:41 +0200 Subject: [PATCH 01/10] added USART library, some subroutines, and test --- firmware/Makefile | 2 +- firmware/main.c | 5 +- firmware/usart.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++ firmware/usart.h | 34 ++++++++++++ 4 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 firmware/usart.c create mode 100644 firmware/usart.h diff --git a/firmware/Makefile b/firmware/Makefile index 9a0f19f..c805113 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -35,7 +35,7 @@ OPT = s ########################################################################################################## # List C source files here. (C dependencies are automatically generated.) -SRC = main.c synth.c +SRC = main.c synth.c usart.c ########################################################################################################## diff --git a/firmware/main.c b/firmware/main.c index 04da2ca..8f91f70 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -6,7 +6,7 @@ #include "main.h" #include "synth.h" - +#include "usart.h" static void init_sampletimer(void) { @@ -74,6 +74,7 @@ int main(void) { /* hardware initialisation: */ init_leds(); + USART0_Init(); // init_motor(); init_pwm(); init_sampletimer(); @@ -94,5 +95,7 @@ ISR(TIMER0_COMPA_vect) { /* calculate next analog sample value in synth mixer:*/ OCR1B = synth_mix(); + USART0_put_uint16(0x1234); + USART0_crlf(); } diff --git a/firmware/usart.c b/firmware/usart.c new file mode 100644 index 0000000..0937238 --- /dev/null +++ b/firmware/usart.c @@ -0,0 +1,132 @@ +/* + * PentaFnord Firmware + * + * by Alexander Lorz + * + * + * The USART control code is derived by code from the 4CHLED project + * by sebseb7: https://github.com/sebseb7/eagle/tree/master/4CHLED/firmware + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include + +//#include "main.h" +#include "usart.h" + +#define UART_RXBUFSIZE 32 + +volatile static uint8_t rxbuf0[UART_RXBUFSIZE]; +volatile static uint8_t *volatile rxhead0, *volatile rxtail0; +//volatile uint8_t xon = 0; + + +ISR (USART_RX_vect) +{ + UCSR0B &= ~(1 << RXCIE0); + asm volatile("sei"); + + int diff; + uint8_t c; + c=UDR0; + diff = rxhead0 - rxtail0; + if (diff < 0) diff += UART_RXBUFSIZE; + if (diff < UART_RXBUFSIZE -1) + { + *rxhead0 = c; + ++rxhead0; + if (rxhead0 == (rxbuf0 + UART_RXBUFSIZE)) rxhead0 = rxbuf0; +// if((diff > 100)&&(xon==0)) +// { +// xon=1; +// //set the CTS pin +// } + } + UCSR0B |= (1 << RXCIE0); +} + + +void USART0_Init (void) +{ + // set baudrate + #undef BAUD + #define BAUD 115200 + #include + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; + + //#if USE_2X + UCSR0A |= (1 << U2X0); // enable double speed operation + //#else + // UCSR0A &= ~(1 << U2X0); // disable double speed operation + //#endif + + + // flush receive buffer + while ( UCSR0A & (1 << RXC0) ) UDR0; + + // set 8N1 + UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); + UCSR0B &= ~(1 << UCSZ02); + + UCSR0B |= (1 << RXEN0)|(1 << TXEN0); //enable send and receive + + UCSR0B |= (1 << RXCIE0); //enable receive interrup + + rxhead0 = rxtail0 = rxbuf0; + +} + + + +void USART0_putc (char c) +{ + + loop_until_bit_is_set(UCSR0A, UDRE0); + UDR0 = c; +} + + +uint8_t USART0_Getc_nb(uint8_t *c) +{ + if (rxhead0==rxtail0) return 0; + *c = *rxtail0; + if (++rxtail0 == (rxbuf0 + UART_RXBUFSIZE)) rxtail0 = rxbuf0; + +// uint8_t diff = rxhead0 - rxtail0; +// if((diff < 10)&&(xon==1)) +// { +// xon=0; +// //set the CTS pin +// } + + return 1; +} + +void USART0_crlf(){ + USART0_putc(0x0A); //newline + USART0_putc(0x0D); //carriage return +}; + +void USART0_put_uint8(uint8_t x){ + USART0_putc(((x & 0b11110000)>>4)+0x30); + USART0_putc((x & 0b00001111)+0x30); + +} +void USART0_put_uint16(uint16_t x){ + USART0_put_uint8 ((x & 0xFF00)>>8); + USART0_put_uint8 (x & 0x00FF); + +} diff --git a/firmware/usart.h b/firmware/usart.h new file mode 100644 index 0000000..d0ddebc --- /dev/null +++ b/firmware/usart.h @@ -0,0 +1,34 @@ +/* + * PentaFnord Firmware + * + * by Alexander Lorz + * + * + * The USART control code is derived by code from the 4CHLED project + * by sebseb7: https://github.com/sebseb7/eagle/tree/master/4CHLED/firmware + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef _USART_H +#define _USART_H + +void USART0_Init (void); +void USART0_putc (char c); +uint8_t USART0_Getc_nb(uint8_t*); +void USART0_put_uint8(uint8_t); +void USART0_crlf(); +void USART0_put_uint16(uint16_t); + +#endif + From a5c2cfebeaa65761a6a1d1bc28ab5eb6330f46ef Mon Sep 17 00:00:00 2001 From: bigalex Date: Tue, 7 Aug 2012 20:08:57 +0200 Subject: [PATCH 02/10] removed USART test from ISR --- firmware/main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/firmware/main.c b/firmware/main.c index 8f91f70..d241f46 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -85,7 +85,13 @@ int main(void) /* here the show begins:*/ sei(); - for(;;) /* ever */ ; + for(;;) /* ever */ { + + //do something + + USART0_put_uint16(0x2342); + USART0_crlf(); + }; /* never */ return 0; } @@ -95,7 +101,5 @@ ISR(TIMER0_COMPA_vect) { /* calculate next analog sample value in synth mixer:*/ OCR1B = synth_mix(); - USART0_put_uint16(0x1234); - USART0_crlf(); } From cad2ccb2e73951ebcf323a142ee0063841d3b392 Mon Sep 17 00:00:00 2001 From: twobit Date: Wed, 8 Aug 2012 02:03:53 +0200 Subject: [PATCH 03/10] tune file reader (not working/done yet) --- synth/{make_freq_table.py => freq_table.py} | 0 synth/main.c | 146 +++++++++++++++++++- synth/simple.tune | 64 +++++++++ synth/synth.c | 106 +++++++++++++- synth/synth.h | 44 +++++- 5 files changed, 353 insertions(+), 7 deletions(-) rename synth/{make_freq_table.py => freq_table.py} (100%) create mode 100644 synth/simple.tune mode change 120000 => 100644 synth/synth.c mode change 120000 => 100644 synth/synth.h diff --git a/synth/make_freq_table.py b/synth/freq_table.py similarity index 100% rename from synth/make_freq_table.py rename to synth/freq_table.py diff --git a/synth/main.c b/synth/main.c index e699ac0..7bd195f 100644 --- a/synth/main.c +++ b/synth/main.c @@ -1,29 +1,165 @@ #include #include #include +#include #include #include "synth.h" +enum { MIXRATE = 8000000 / (6 * 64) }; + +static SDL_AudioSpec spec = { MIXRATE, AUDIO_U16SYS, 1, 0, 1024, }; + static void fill_buffer(void* userdata, Uint8* stream, int len) { - for(int i = 0; i < len / 2; i++) ((uint16_t*)stream)[i] = synth_mix() * 50; + for(int i = 0; i < len / 2; i++) { + uint16_t m = synth_mix(); + assert(m < 0x100); + ((uint16_t*)stream)[i] = m * 50; + } } -SDL_AudioSpec spec = { 8000000 / (3 * 64), AUDIO_U16SYS, 1, 0, 1024, }; +// this parser is a complete hack +// put i can't care less right now +static int parse_tune(const char* filename) { + char line[256]; + FILE* file = fopen(filename, "r"); + if(!file) return -1; -int main(int argc ,char** argv) { - synth_init(); + char wave_names[256][256]; + memset(wave_names, 0, sizeof(wave_names)); + int wave_counter = 0; + + + char inst_names[256][256]; + memset(inst_names, 0, sizeof(inst_names)); + int inst_counter = 0; + + + char pattern_names[256][256]; + memset(pattern_names, 0, sizeof(pattern_names)); + int pattern_counter = 0; + + + int state = 0; + int line_nr = 0; + while(fgets(line, 256, file)) { + line_nr++; + + // skip empty line + if(line[0] == '\n') continue; + + // comments + if(line[0] == '#') continue; + + if(state == 0) { + if(strcmp("[WAVETABLE]\n", line)) return line_nr; + state = 1; + } + else if(state == 1) { + if(line[0] == '[') { + if(strcmp("[INSTRUMENTS]\n", line)) return line_nr; + state = 2; + } + else if(isalpha(line[0])) { + sscanf(line, "%s", wave_names[wave_counter]); + } + else if(line[0] == '\t') { + int a, b; + if(sscanf(line + 1, "%u %u", &a, &b) != 2) return line_nr; + wave_table[wave_counter][0] = a; + wave_table[wave_counter][1] = b; + wave_counter++; + } + else return line_nr; + } + else if(state == 2) { + if(line[0] == '[') { + if(strcmp("[PATTERNS]\n", line)) return line_nr; + state = 3; + } + else { + char wave_name[256]; + int pw, ps, d; + if(sscanf(line, "%s %u %u %u %s", + inst_names[inst_counter], &pw, &ps, &d, + wave_name) != 5) return line_nr; + + instruments[inst_counter].pulse_width = pw; + instruments[inst_counter].pulse_sweep = ps; + instruments[inst_counter].decay = d; + int i; + for(i = 0; i < 256; i++) + if(strcmp(wave_names[i], wave_name) == 0) break; + if(i == 256) return line_nr; + instruments[inst_counter].wave_table_pos = i; + inst_counter++; + } + } + else if(state == 3) { + if(line[0] == '[') { + if(strcmp("[PATTERNTABLE]\n", line)) return line_nr; + state = 4; + } + else { + if(!isalpha(line[0])) return line_nr; + sscanf(line, "%s", pattern_names[wave_counter]); + for(int i = 0; i < pattern_length && fgets(line, 256, file); i++) { + if(line[0] != '\t') return line_nr; + char* p = strch("aabccddeffgg" ,line[1]); + // TODO + if(p) { + patterns[pattern_counter][i][0] = line - p + (line[2] == '#') + (line[3] - '0') * 12; + int a; + sscanf(line + 4, "") + + patterns[pattern_counter][i][1] = a; + } + + } + pattern_counter++; + } + + + + } + else { + + + + } + } + if(state =! 4) return line_nr; + + + fclose(file); + return 0; +} + + + + +int main(int argc, char** argv) { + if(argc != 2) { + printf("usage: %s tunefile\n", argv[0]); + return 0; + } + + int error = parse_tune(argv[1]); + if(error != 0) { + fprintf(stderr, "%d: parsing error\n", error); + return 1; + } spec.callback = &fill_buffer; if(SDL_OpenAudio(&spec, &spec) < 0) { fprintf(stderr, "ERROR"); exit(1); } - printf("freq = %d\n", spec.freq); SDL_PauseAudio(0); + puts("playing..."); getchar(); diff --git a/synth/simple.tune b/synth/simple.tune new file mode 100644 index 0000000..de4262b --- /dev/null +++ b/synth/simple.tune @@ -0,0 +1,64 @@ +[WAVETABLE] + +bass00 + 0 3 + 0 1 + 255 255 + +bass01 + 0 2 + 255 255 + + + +[INSTRUMENTS] + +bass00 32768 10 0 bass00 +bass01 32768 10 0 bass01 + + +[PATTERNS] + +empty + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + +bass + c_3 + --- + c_4 + --- + c_3 + --- + c_4 + --- + c_3 + --- + c_4 + --- + c_3 + --- + c_4 + --- + + + +[PATTERNTABLE] + +bass empty empty +bass empty empty + diff --git a/synth/synth.c b/synth/synth.c deleted file mode 120000 index 482a33e..0000000 --- a/synth/synth.c +++ /dev/null @@ -1 +0,0 @@ -../firmware/synth.c \ No newline at end of file diff --git a/synth/synth.c b/synth/synth.c new file mode 100644 index 0000000..eade3fe --- /dev/null +++ b/synth/synth.c @@ -0,0 +1,105 @@ +#include +#include "synth.h" +#include "freq_table.h" + + +synth_instrument_t instruments[256]; +uint8_t wave_table[256][2]; +uint8_t patterns[256][pattern_length][2]; +uint8_t pattern_table[256][channel_count]; +uint8_t tune_length; + +int16_t sample; +int8_t tick; +int8_t row; +int8_t seq; + + +static synth_channel_t channels[channel_count]; + + +uint16_t synth_mix(void) +{ + if(sample == 0) { // new tick + for(int i = 0; i < channel_count; i++) { + synth_channel_t* chan = &channels[i]; + + const synth_instrument_t* inst = &instruments[chan->inst_nr]; + + if(chan->level > inst->decay) chan->level -= inst->decay; + else chan->level = 0; + + chan->pulse_width += inst->pulse_sweep; + + + chan->pos++; + if(wave_table[chan->pos][1] == 0xff) chan->pos += wave_table[chan->pos][0]; + + + // enter new row + if(tick == 0) { + uint8_t pattern_nr = pattern_table[seq][i]; + uint8_t note = patterns[pattern_nr][row][0]; + + if(note) { // new note, maybe? + if(note == 0xff) { + chan->level = 0; + } else { + chan->level = 80; // TODO: less? + chan->note = note; + chan->inst_nr = patterns[pattern_nr][row][1]; + inst = &instruments[chan->inst_nr]; + chan->pos = inst->wave_table_pos; + if(inst->pulse_width) chan->pulse_width = inst->pulse_width; + } + } + } + } + } + if(++sample == tick_length) { + sample = 0; + if(++tick == row_length) { + tick = 0; + if(++row == pattern_length) { + row = 0; + if(++seq == tune_length) { + seq = 0; + } + } + } + } + + + uint16_t output = 0; + for(int i = 0; i < channel_count; i++) { + synth_channel_t* chan = &channels[i]; + const synth_instrument_t* inst = &instruments[chan->inst_nr]; + + chan->phase += freq_table[(uint8_t)(chan->note + wave_table[chan->pos][0])]; + + uint8_t amp; + switch(wave_table[chan->pos][1]) { + case WAVE_PULSE: + amp = -(chan->phase < chan->pulse_width); + break; + + case WAVE_SAW: + amp = (chan->phase >> 8); + break; + + case WAVE_NOISE: // shitty noise + chan->phase = (chan->phase >> 1) ^ (-(chan->phase & 1) & 0xb400); + amp = (chan->phase >> 8); + break; + + default: + amp = 0; + break; + } + + output += ((amp & 0xff) * chan->level) >> 8; + } + + return output; +} + diff --git a/synth/synth.h b/synth/synth.h deleted file mode 120000 index c1ea587..0000000 --- a/synth/synth.h +++ /dev/null @@ -1 +0,0 @@ -../firmware/synth.h \ No newline at end of file diff --git a/synth/synth.h b/synth/synth.h new file mode 100644 index 0000000..4cda049 --- /dev/null +++ b/synth/synth.h @@ -0,0 +1,43 @@ +enum { WAVE_OFF, WAVE_PULSE, WAVE_SAW, WAVE_NOISE }; + +typedef struct { + uint8_t note; + uint8_t inst_nr; + uint8_t pos; + + uint16_t phase; + uint16_t pulse_width; + + uint8_t level; // envelop level + +} synth_channel_t; + + +typedef struct { + uint16_t pulse_width; + uint8_t pulse_sweep; + uint8_t decay; + uint8_t wave_table_pos; +} synth_instrument_t; + + +uint16_t synth_mix(void); + +enum { + channel_count = 3, + tick_length = 400, + row_length = 4, + pattern_length = 16 +}; + + +extern synth_instrument_t instruments[256]; +extern uint8_t wave_table[256][2]; +extern uint8_t patterns[256][pattern_length][2]; +extern uint8_t pattern_table[256][channel_count]; +extern uint8_t tune_length; + +extern int16_t sample; +extern int8_t tick; +extern int8_t row; +extern int8_t seq; From f37519c06f9d240fc26ae2ddf8b8cf1d3c97b91d Mon Sep 17 00:00:00 2001 From: twobit Date: Wed, 8 Aug 2012 03:23:52 +0200 Subject: [PATCH 04/10] parser done --- synth/main.c | 55 ++++++++++++++++++++++++++++++++++++----------- synth/simple.tune | 44 ++++++++++++++++++++++++------------- 2 files changed, 72 insertions(+), 27 deletions(-) diff --git a/synth/main.c b/synth/main.c index 7bd195f..b373497 100644 --- a/synth/main.c +++ b/synth/main.c @@ -22,7 +22,6 @@ static void fill_buffer(void* userdata, Uint8* stream, int len) { // this parser is a complete hack // put i can't care less right now static int parse_tune(const char* filename) { - char line[256]; FILE* file = fopen(filename, "r"); if(!file) return -1; @@ -41,9 +40,12 @@ static int parse_tune(const char* filename) { memset(pattern_names, 0, sizeof(pattern_names)); int pattern_counter = 0; + tune_length = 0; + int state = 0; int line_nr = 0; + char line[256]; while(fgets(line, 256, file)) { line_nr++; @@ -80,18 +82,18 @@ static int parse_tune(const char* filename) { state = 3; } else { - char wave_name[256]; + char wave[256]; int pw, ps, d; if(sscanf(line, "%s %u %u %u %s", inst_names[inst_counter], &pw, &ps, &d, - wave_name) != 5) return line_nr; + wave) != 5) return line_nr; instruments[inst_counter].pulse_width = pw; instruments[inst_counter].pulse_sweep = ps; instruments[inst_counter].decay = d; int i; for(i = 0; i < 256; i++) - if(strcmp(wave_names[i], wave_name) == 0) break; + if(strcmp(wave_names[i], wave) == 0) break; if(i == 256) return line_nr; instruments[inst_counter].wave_table_pos = i; inst_counter++; @@ -104,18 +106,35 @@ static int parse_tune(const char* filename) { } else { if(!isalpha(line[0])) return line_nr; - sscanf(line, "%s", pattern_names[wave_counter]); + sscanf(line, "%s", pattern_names[pattern_counter]); for(int i = 0; i < pattern_length && fgets(line, 256, file); i++) { + line_nr++; if(line[0] != '\t') return line_nr; - char* p = strch("aabccddeffgg" ,line[1]); - // TODO + char note[256]; + char inst[256]; + int m = sscanf(line + 1, "%s %s", note, inst); + if(m == 0) return line_nr; + char* s = "ccddeffggaab"; + char* p = strchr(s, line[1]); if(p) { - patterns[pattern_counter][i][0] = line - p + (line[2] == '#') + (line[3] - '0') * 12; - int a; - sscanf(line + 4, "") + patterns[pattern_counter][i][0] = (p - s) + + (note[1] == '#') + (note[2] - '0') * 12; + int j; + for(j = 0; j < 256; j++) + if(strcmp(inst_names[j], inst) == 0) break; + if(j == 256) return line_nr; + patterns[pattern_counter][i][1] = j; - patterns[pattern_counter][i][1] = a; } + else if(m == 1) { + if(strcmp("-", note) == 0) + patterns[pattern_counter][i][0] = 0xff; + else if(strcmp(".", note) == 0) + patterns[pattern_counter][i][0] = 0; + else return line_nr; + + } + else return line_nr; } pattern_counter++; @@ -125,7 +144,19 @@ static int parse_tune(const char* filename) { } else { - + char* p = line; + char pat[256]; + for(int i = 0; i < channel_count; i ++) { + sscanf(p, "%s", pat); + int j; + for(j = 0; j < 256; j++) + if(strcmp(pattern_names[j], pat) == 0) break; + if(j == 256) return line_nr; + pattern_table[tune_length][i] = j; + while(*p && !isspace(*p)) p++; + while(*p && isspace(*p)) p++; + } + tune_length++; } diff --git a/synth/simple.tune b/synth/simple.tune index de4262b..08d8cb1 100644 --- a/synth/simple.tune +++ b/synth/simple.tune @@ -9,13 +9,28 @@ bass01 0 2 255 255 +pad00 + 0 2 + 3 2 + 7 2 + 12 2 + 252 255 +pad01 + 0 2 + 4 2 + 7 2 + 12 2 + 252 255 [INSTRUMENTS] bass00 32768 10 0 bass00 bass01 32768 10 0 bass01 +pad00 32768 10 3 pad00 +pad01 32768 10 3 pad01 + [PATTERNS] @@ -38,23 +53,22 @@ empty . bass + c_3 bass00 + - + c_5 pad00 + c_3 bass00 + - + . c_3 - --- - c_4 - --- + - c_3 - --- - c_4 - --- - c_3 - --- - c_4 - --- - c_3 - --- - c_4 - --- - + - + . + . + a#4 pad01 + . + c_3 bass00 + - [PATTERNTABLE] From eef4ec0e441db62ad7097cec54f58c11f24e54b9 Mon Sep 17 00:00:00 2001 From: twobit Date: Wed, 8 Aug 2012 03:24:21 +0200 Subject: [PATCH 05/10] slow donw, put stuff into header --- firmware/main.c | 4 ++-- firmware/synth.c | 43 +++++++------------------------------------ firmware/synth.h | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/firmware/main.c b/firmware/main.c index d241f46..74ce931 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -18,7 +18,7 @@ static void init_sampletimer(void) TCCR0A = (1 << WGM01); TCCR0B = (1 << CS00) | (1 << CS01); - OCR0A = 3; /* TOP */ + OCR0A = 6; /* TOP */ TCNT0 = 0; /*enable interrupt*/ TIMSK0 |= (1< +#include "synth.h" #include "freq_table.h" // sample rate is 8M / (3 * 64) - -enum { WAVE_OFF, WAVE_PULSE, WAVE_SAW, WAVE_NOISE }; enum { channel_count = 3, - tick_length = 800, + tick_length = 400, row_length = 4, pattern_length = 16 }; -typedef struct { - uint8_t note; - uint8_t inst_nr; - uint8_t pos; - - uint16_t phase; - uint16_t pulse_width; - - uint8_t level; // envelop level - -} synth_channel_t; - - -typedef struct { - uint16_t pulse_width; - uint8_t pulse_sweep; - uint8_t wave_table_pos; - uint8_t decay; - -} synth_instrument_t; static const synth_instrument_t instruments[] = { @@ -68,9 +47,9 @@ static const uint8_t patterns[][pattern_length][2] = { {}, { { 33 - 12, 0 }, + { 0, 0 }, { 0xff, 1 }, - { 33 - 12, 1 }, - { 0xff, 1 }, + { 0, 0 }, { 33, 1 }, { 0xff, 1 }, { 33, 1 }, @@ -86,9 +65,9 @@ static const uint8_t patterns[][pattern_length][2] = { }, { { 28 - 12, 0 }, + { 0, 0 }, { 0xff, 1 }, - { 28 - 12, 1 }, - { 0xff, 1 }, + { 0, 0 }, { 28, 1 }, { 0xff, 1 }, { 28, 1 }, @@ -202,14 +181,6 @@ void synth_init(void) tick = 0; row = 0; seq = 0; - -/* - // some test values - channels[0].wave = WAVE_PULSE; - channels[0].pulse_width = 1 << 15; - - channels[1].wave = WAVE_SAW; -*/ } uint16_t synth_mix(void) @@ -239,7 +210,7 @@ uint16_t synth_mix(void) if(note == 0xff) { chan->level = 0; } else { - chan->level = 100; + chan->level = 80; // TODO: less? chan->note = note; chan->inst_nr = patterns[pattern_nr][row][1]; inst = &instruments[chan->inst_nr]; diff --git a/firmware/synth.h b/firmware/synth.h index 6b90c0f..24f0088 100644 --- a/firmware/synth.h +++ b/firmware/synth.h @@ -1,3 +1,26 @@ +enum { WAVE_OFF, WAVE_PULSE, WAVE_SAW, WAVE_NOISE }; + +typedef struct { + uint8_t note; + uint8_t inst_nr; + uint8_t pos; + + uint16_t phase; + uint16_t pulse_width; + + uint8_t level; // envelop level + +} synth_channel_t; + + +typedef struct { + uint16_t pulse_width; + uint8_t pulse_sweep; + uint8_t wave_table_pos; + uint8_t decay; + +} synth_instrument_t; + void synth_init(void); uint16_t synth_mix(void); From e4fe7d04324ab235b815b27975f75c9533fe15a3 Mon Sep 17 00:00:00 2001 From: twobit Date: Wed, 8 Aug 2012 03:41:25 +0200 Subject: [PATCH 06/10] some more bleepy shit --- synth/simple.tune | 130 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 14 deletions(-) diff --git a/synth/simple.tune b/synth/simple.tune index 08d8cb1..731219e 100644 --- a/synth/simple.tune +++ b/synth/simple.tune @@ -1,12 +1,8 @@ [WAVETABLE] -bass00 - 0 3 - 0 1 - 255 255 -bass01 - 0 2 +bass + 0 1 255 255 pad00 @@ -23,14 +19,42 @@ pad01 12 2 252 255 + +kick + 0 3 + 0 1 + 254 1 + 248 1 + 244 1 + 0 255 + 255 255 + +snare + 0 3 + 0 1 + 254 1 + 248 1 + 244 1 + 0 3 + 255 255 + +hat + 0 3 + 255 255 + + + [INSTRUMENTS] -bass00 32768 10 0 bass00 -bass01 32768 10 0 bass01 +bass 32768 10 0 bass pad00 32768 10 3 pad00 pad01 32768 10 3 pad01 +kick 32768 0 3 kick +snare 32768 0 10 snare +hat 0 0 40 hat + [PATTERNS] @@ -52,11 +76,65 @@ empty . . -bass - c_3 bass00 +drum00 + d_3 kick + . + d_3 hat + . + d_4 snare + . + d_3 kick + . + d_3 hat + . + d_3 hat + . + d_4 snare + . + d_3 kick + . + +drum01 + d_3 kick + . + d_3 hat + . + d_4 snare + . + d_3 kick + . + d_3 hat + . + d_3 hat + . + d_4 snare + . + d_3 hat + . + +drum02 + d_3 kick + . + d_3 hat + . + d_4 snare + . + d_3 kick + . + d_4 snare + . + d_3 kick + . + d_4 snare + . + d_4 snare + . + +bass00 + c_3 bass - c_5 pad00 - c_3 bass00 + c_3 bass - . c_3 @@ -67,12 +145,36 @@ bass . a#4 pad01 . - c_3 bass00 + c_4 bass - +bass01 + c_3 bass + - + c_5 pad00 + c_3 bass + - + . + c_3 + - + c_3 + - + . + . + a#4 pad01 + . + . + . [PATTERNTABLE] +empty bass00 empty +empty bass00 empty + +drum00 bass00 empty +drum01 bass01 empty +drum00 bass00 empty +drum01 bass00 empty +drum00 bass00 empty +drum02 bass01 empty -bass empty empty -bass empty empty From b5286220c2d634f3b9b91df40c8cc22a24c9105a Mon Sep 17 00:00:00 2001 From: twobit Date: Wed, 8 Aug 2012 03:45:58 +0200 Subject: [PATCH 07/10] good night --- synth/simple.tune | 36 ++++++++++++++++++------------------ synth/synth.h | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/synth/simple.tune b/synth/simple.tune index 731219e..c5a17bc 100644 --- a/synth/simple.tune +++ b/synth/simple.tune @@ -77,53 +77,53 @@ empty . drum00 - d_3 kick + g_3 kick . - d_3 hat + g_3 hat . d_4 snare . - d_3 kick + g_3 kick . - d_3 hat + g_3 hat . - d_3 hat + g_3 hat . d_4 snare . - d_3 kick + g_3 kick . drum01 - d_3 kick + g_3 kick . - d_3 hat + g_3 hat . d_4 snare . - d_3 kick + g_3 kick . - d_3 hat + g_3 hat . - d_3 hat + g_3 hat . d_4 snare . - d_3 hat + g_3 hat . drum02 - d_3 kick + g_3 kick . - d_3 hat + g_3 hat . d_4 snare . - d_3 kick + g_3 kick . d_4 snare . - d_3 kick + g_3 kick . d_4 snare . @@ -169,9 +169,9 @@ bass01 [PATTERNTABLE] empty bass00 empty empty bass00 empty +empty bass00 empty +empty bass01 empty -drum00 bass00 empty -drum01 bass01 empty drum00 bass00 empty drum01 bass00 empty drum00 bass00 empty diff --git a/synth/synth.h b/synth/synth.h index 4cda049..c43e08f 100644 --- a/synth/synth.h +++ b/synth/synth.h @@ -25,7 +25,7 @@ uint16_t synth_mix(void); enum { channel_count = 3, - tick_length = 400, + tick_length = 500, row_length = 4, pattern_length = 16 }; From d1d3fd9b61431add77be80e904efaeb5fcb63e65 Mon Sep 17 00:00:00 2001 From: twobit Date: Wed, 8 Aug 2012 20:37:26 +0200 Subject: [PATCH 08/10] allow symbles --- synth/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/synth/main.c b/synth/main.c index b373497..7ef00bb 100644 --- a/synth/main.c +++ b/synth/main.c @@ -64,7 +64,7 @@ static int parse_tune(const char* filename) { if(strcmp("[INSTRUMENTS]\n", line)) return line_nr; state = 2; } - else if(isalpha(line[0])) { + else if(!isspace(line[0])) { sscanf(line, "%s", wave_names[wave_counter]); } else if(line[0] == '\t') { @@ -105,7 +105,7 @@ static int parse_tune(const char* filename) { state = 4; } else { - if(!isalpha(line[0])) return line_nr; + if(isspace(line[0])) return line_nr; sscanf(line, "%s", pattern_names[pattern_counter]); for(int i = 0; i < pattern_length && fgets(line, 256, file); i++) { line_nr++; @@ -127,7 +127,7 @@ static int parse_tune(const char* filename) { } else if(m == 1) { - if(strcmp("-", note) == 0) + if(strcmp("---", note) == 0) patterns[pattern_counter][i][0] = 0xff; else if(strcmp(".", note) == 0) patterns[pattern_counter][i][0] = 0; From ab6d5cbdeee27740f20b32a0cc0d16391df371d7 Mon Sep 17 00:00:00 2001 From: twobit Date: Wed, 8 Aug 2012 20:37:49 +0200 Subject: [PATCH 09/10] better tune, maybe --- synth/simple.tune | 157 +++++++++++++++++++++++++++++++++------------- synth/synth.h | 4 +- 2 files changed, 117 insertions(+), 44 deletions(-) diff --git a/synth/simple.tune b/synth/simple.tune index c5a17bc..10dc44f 100644 --- a/synth/simple.tune +++ b/synth/simple.tune @@ -2,6 +2,7 @@ bass + 250 1 0 1 255 255 @@ -21,11 +22,10 @@ pad01 kick - 0 3 - 0 1 - 254 1 - 248 1 - 244 1 + 255 1 + 251 1 + 246 1 + 242 1 0 255 255 255 @@ -38,27 +38,31 @@ snare 0 3 255 255 -hat - 0 3 +lead + 0 2 255 255 +lead_ + 255 2 + 0 2 + 255 255 [INSTRUMENTS] -bass 32768 10 0 bass +bass 32768 10 4 bass pad00 32768 10 3 pad00 pad01 32768 10 3 pad01 kick 32768 0 3 kick -snare 32768 0 10 snare -hat 0 0 40 hat +snare 30000 0 10 snare +lead 1000 255 1 lead +lead_ 1000 255 1 lead_ [PATTERNS] - -empty +--- . . . @@ -79,15 +83,15 @@ empty drum00 g_3 kick . - g_3 hat . + g_3 kick d_4 snare . g_3 kick . - g_3 hat . - g_3 hat + . + . . d_4 snare . @@ -97,68 +101,68 @@ drum00 drum01 g_3 kick . - g_3 hat . + g_3 kick d_4 snare . g_3 kick . - g_3 hat . - g_3 hat + . + . . d_4 snare . - g_3 hat + . . drum02 g_3 kick . - g_3 hat . + g_3 kick d_4 snare . g_3 kick . - d_4 snare + . . g_3 kick . d_4 snare . d_4 snare - . + d_4 snare bass00 c_3 bass - - + --- c_5 pad00 c_3 bass - - + --- . - c_3 - - - c_3 - - + c_3 bass + d#5 pad01 + c_3 bass + --- . . a#4 pad01 . c_4 bass - - + c_4 bass bass01 c_3 bass - - + --- c_5 pad00 c_3 bass - - + --- . c_3 - - + --- c_3 - - + --- . . a#4 pad01 @@ -166,15 +170,84 @@ bass01 . . + +lead00 + . + . + g_5 lead + --- + g_5 lead_ + . + . + . + --- + . + f_5 lead + d#5 + f_5 + d#5 + f_5 + g_5 + +lead01 + f_5 lead + c_5 + --- + c_5 + . + . + --- + c_5 + d#5 + c_5 + f_5 + c_5 + g_5 + d#5 + a#5 + c_6 lead_ + +lead02 + . + . + g_5 lead + --- + g_5 lead_ + . + . + . + --- + . + f_5 lead + d#5 + f_5 lead_ + d#5 lead + a#4 + c_5 + + [PATTERNTABLE] -empty bass00 empty -empty bass00 empty -empty bass00 empty -empty bass01 empty - -drum00 bass00 empty -drum01 bass00 empty -drum00 bass00 empty -drum02 bass01 empty + + +--- bass00 --- +--- bass01 --- +--- bass00 --- +--- bass01 --- + +--- bass00 lead00 +--- bass01 lead01 +--- bass00 lead02 +--- bass01 --- + +drum00 bass00 lead00 +drum01 bass01 lead01 +drum00 bass00 lead02 +drum02 bass01 --- + +drum00 bass00 lead00 +drum01 bass01 lead01 +drum00 bass00 lead02 +drum02 bass01 --- + diff --git a/synth/synth.h b/synth/synth.h index c43e08f..b094fb3 100644 --- a/synth/synth.h +++ b/synth/synth.h @@ -25,8 +25,8 @@ uint16_t synth_mix(void); enum { channel_count = 3, - tick_length = 500, - row_length = 4, + tick_length = 400, + row_length = 8, pattern_length = 16 }; From d2fa333ec7d48dc5d22b6fc8be741b798a5237c5 Mon Sep 17 00:00:00 2001 From: twobit Date: Wed, 8 Aug 2012 20:41:34 +0200 Subject: [PATCH 10/10] comment song --- synth/simple.tune | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/synth/simple.tune b/synth/simple.tune index 10dc44f..8f6aa06 100644 --- a/synth/simple.tune +++ b/synth/simple.tune @@ -1,5 +1,5 @@ [WAVETABLE] - +# note offset | wave form bass 250 1 @@ -49,6 +49,7 @@ lead_ [INSTRUMENTS] +# pulse width | pulse sweep | decay | label in wave table bass 32768 10 4 bass @@ -62,6 +63,7 @@ lead 1000 255 1 lead lead_ 1000 255 1 lead_ [PATTERNS] +# note | instrument --- . .