From 5cc7df8750503fae22a733d56d9f992a94477cef Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 28 Jul 2017 11:29:26 -0400 Subject: [PATCH 1/5] try out b6 and b7 audio --- keyboards/deltasplit75/v2/config.h | 178 ++++++++++++++--------------- quantum/audio/audio.c | 66 +++++++++-- 2 files changed, 144 insertions(+), 100 deletions(-) diff --git a/keyboards/deltasplit75/v2/config.h b/keyboards/deltasplit75/v2/config.h index d1f6f7966c..0f4b806e2d 100644 --- a/keyboards/deltasplit75/v2/config.h +++ b/keyboards/deltasplit75/v2/config.h @@ -1,90 +1,90 @@ -/* -Copyright 2012 Jun Wako - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -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 CONFIG_H -#define CONFIG_H - -#include "config_common.h" - -/* USB Device descriptor parameter */ -#define VENDOR_ID 0xFEED -#define PRODUCT_ID 0x3060 -#define DEVICE_VER 0x0001 -#define MANUFACTURER xyxjj -#define PRODUCT DeltaSplit75 -#define DESCRIPTION 75% split keyboard - -/* key matrix size */ -// Rows are doubled-up -#define MATRIX_ROWS 14 -#define MATRIX_COLS 8 - -// wiring of each half -#define MATRIX_ROW_PINS { F4, F5, F6, F7, B1, B3, B2 } -#define MATRIX_COL_PINS { B6, B5, B4, E6, D7, C6, D4, D1} - -#define CATERINA_BOOTLOADER - -/* COL2ROW or ROW2COL */ -#define DIODE_DIRECTION COL2ROW - -/* define if matrix has ghost */ -//#define MATRIX_HAS_GHOST - -/* number of backlight levels */ -// #define BACKLIGHT_LEVELS 3 - -/* Set 0 if debouncing isn't needed */ -#define DEBOUNCING_DELAY 5 - -/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ -#define LOCKING_SUPPORT_ENABLE -/* Locking resynchronize hack */ -#define LOCKING_RESYNC_ENABLE - -/* key combination for command */ -#define IS_COMMAND() ( \ - keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ -) - -/* ws2812 RGB LED */ -#define RGB_DI_PIN D3 -#define RGBLIGHT_TIMER -#define RGBLED_NUM 12 // Number of LEDs -#define ws2812_PORTREG PORTD -#define ws2812_DDRREG DDRD - -/* - * Feature disable options - * These options are also useful to firmware size reduction. - */ - -/* disable debug print */ -// #define NO_DEBUG - -/* disable print */ -// #define NO_PRINT - -/* disable action features */ -//#define NO_ACTION_LAYER -//#define NO_ACTION_TAPPING -//#define NO_ACTION_ONESHOT -//#define NO_ACTION_MACRO -//#define NO_ACTION_FUNCTION - - +/* +Copyright 2012 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +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 CONFIG_H +#define CONFIG_H + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x3060 +#define DEVICE_VER 0x0001 +#define MANUFACTURER xyxjj +#define PRODUCT DeltaSplit75 +#define DESCRIPTION 75% split keyboard + +/* key matrix size */ +// Rows are doubled-up +#define MATRIX_ROWS 14 +#define MATRIX_COLS 8 + +// wiring of each half +#define MATRIX_ROW_PINS { F4, F5, F6, F7, B1, B3, B2 } +#define MATRIX_COL_PINS { B6, B5, B4, E6, D7, C6, D4, D1} + +#define CATERINA_BOOTLOADER + +/* COL2ROW or ROW2COL */ +#define DIODE_DIRECTION COL2ROW + +/* define if matrix has ghost */ +//#define MATRIX_HAS_GHOST + +/* number of backlight levels */ +// #define BACKLIGHT_LEVELS 3 + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCING_DELAY 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + +/* ws2812 RGB LED */ +#define RGB_DI_PIN D3 +#define RGBLIGHT_TIMER +#define RGBLED_NUM 12 // Number of LEDs +#define ws2812_PORTREG PORTD +#define ws2812_DDRREG DDRD + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +// #define NO_DEBUG + +/* disable print */ +// #define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + + #endif \ No newline at end of file diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 8e8570d26c..adb12d3492 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -44,6 +44,16 @@ #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A) #endif +#ifdef B6_AUDIO + #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1B) + #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1B) +#endif + +#ifdef B7_AUDIO + #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1C) + #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1C) +#endif + // TCCR3A: Timer/Counter #3 Control Register // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 @@ -57,6 +67,16 @@ #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0)); #endif +#ifdef B6_AUDIO + #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1B1); + #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0)); +#endif + +#ifdef B7_AUDIO + #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1C1); + #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0)); +#endif + // Fast PWM Mode Controls #ifdef C6_AUDIO @@ -69,6 +89,16 @@ #define TIMER_1_DUTY_CYCLE OCR1A #endif +#ifdef B6_AUDIO + #define TIMER_1_PERIOD ICR1 + #define TIMER_1_DUTY_CYCLE OCR1B +#endif + +#ifdef B7_AUDIO + #define TIMER_1_PERIOD ICR1 + #define TIMER_1_DUTY_CYCLE OCR1C +#endif + // ----------------------------------------------------------------------------- @@ -153,11 +183,25 @@ void audio_init() PORTB &= ~_BV(PORTB5); #endif + #ifdef B6_AUDIO + DDRB |= _BV(PORTB6); + #else + DDRB |= _BV(PORTB6); + PORTB &= ~_BV(PORTB6); + #endif + + #ifdef B7_AUDIO + DDRB |= _BV(PORTB7); + #else + DDRB |= _BV(PORTB7); + PORTB &= ~_BV(PORTB7); + #endif + #ifdef C6_AUDIO DISABLE_AUDIO_COUNTER_3_ISR; #endif - #ifdef B5_AUDIO + #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) DISABLE_AUDIO_COUNTER_1_ISR; #endif @@ -171,7 +215,7 @@ void audio_init() TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); #endif - #ifdef B5_AUDIO + #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10); TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); #endif @@ -199,7 +243,7 @@ void stop_all_notes() DISABLE_AUDIO_COUNTER_3_OUTPUT; #endif - #ifdef B5_AUDIO + #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) DISABLE_AUDIO_COUNTER_1_ISR; DISABLE_AUDIO_COUNTER_1_OUTPUT; #endif @@ -249,7 +293,7 @@ void stop_note(float freq) DISABLE_AUDIO_COUNTER_3_ISR; DISABLE_AUDIO_COUNTER_3_OUTPUT; #endif - #ifdef B5_AUDIO + #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) DISABLE_AUDIO_COUNTER_1_ISR; DISABLE_AUDIO_COUNTER_1_OUTPUT; #endif @@ -289,7 +333,7 @@ ISR(TIMER3_COMPA_vect) if (playing_note) { if (voices > 0) { - #ifdef B5_AUDIO + #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) float freq_alt = 0; if (voices > 1) { if (polyphony_rate == 0) { @@ -463,10 +507,10 @@ ISR(TIMER3_COMPA_vect) } #endif -#ifdef B5_AUDIO +#if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) ISR(TIMER1_COMPA_vect) { - #if defined(B5_AUDIO) && !defined(C6_AUDIO) + #if (defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)) && !defined(C6_AUDIO) float freq = 0; if (playing_note) { @@ -616,7 +660,7 @@ void play_note(float freq, int vol) { #ifdef C6_AUDIO DISABLE_AUDIO_COUNTER_3_ISR; #endif - #ifdef B5_AUDIO + #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) DISABLE_AUDIO_COUNTER_1_ISR; #endif @@ -638,7 +682,7 @@ void play_note(float freq, int vol) { ENABLE_AUDIO_COUNTER_3_ISR; ENABLE_AUDIO_COUNTER_3_OUTPUT; #endif - #ifdef B5_AUDIO + #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) #ifdef C6_AUDIO if (voices > 1) { ENABLE_AUDIO_COUNTER_1_ISR; @@ -665,7 +709,7 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) #ifdef C6_AUDIO DISABLE_AUDIO_COUNTER_3_ISR; #endif - #ifdef B5_AUDIO + #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) DISABLE_AUDIO_COUNTER_1_ISR; #endif @@ -691,7 +735,7 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) ENABLE_AUDIO_COUNTER_3_ISR; ENABLE_AUDIO_COUNTER_3_OUTPUT; #endif - #ifdef B5_AUDIO + #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) #ifndef C6_AUDIO ENABLE_AUDIO_COUNTER_1_ISR; ENABLE_AUDIO_COUNTER_1_OUTPUT; From 8582faab6f359546be1caca513dafe4ef9782526 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 3 Jan 2018 14:32:10 -0500 Subject: [PATCH 2/5] add planck audio out config --- keyboards/planck/keymaps/audio_out/config.h | 46 ++++ keyboards/planck/keymaps/audio_out/keymap.c | 264 ++++++++++++++++++++ keyboards/planck/keymaps/audio_out/rules.mk | 3 + keyboards/planck/rules.mk | 2 +- 4 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 keyboards/planck/keymaps/audio_out/config.h create mode 100644 keyboards/planck/keymaps/audio_out/keymap.c create mode 100644 keyboards/planck/keymaps/audio_out/rules.mk diff --git a/keyboards/planck/keymaps/audio_out/config.h b/keyboards/planck/keymaps/audio_out/config.h new file mode 100644 index 0000000000..83caf12662 --- /dev/null +++ b/keyboards/planck/keymaps/audio_out/config.h @@ -0,0 +1,46 @@ +#ifndef CONFIG_USER_H +#define CONFIG_USER_H + +#include "config_common.h" + +#ifdef AUDIO_ENABLE + #define STARTUP_SONG SONG(PLANCK_SOUND) + // #define STARTUP_SONG SONG(NO_SOUND) + + #define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \ + SONG(COLEMAK_SOUND), \ + SONG(DVORAK_SOUND) \ + } +#endif + +#define MUSIC_MASK (keycode != KC_NO) + +/* + * MIDI options + */ + +/* Prevent use of disabled MIDI features in the keymap */ +//#define MIDI_ENABLE_STRICT 1 + +/* enable basic MIDI features: + - MIDI notes can be sent when in Music mode is on +*/ + +#define MIDI_BASIC + +/* enable advanced MIDI features: + - MIDI notes can be added to the keymap + - Octave shift and transpose + - Virtual sustain, portamento, and modulation wheel + - etc. +*/ +//#define MIDI_ADVANCED + +/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */ +//#define MIDI_TONE_KEYCODE_OCTAVES 2 + +#define B7_AUDIO + +#undef BACKLIGHT_PIN + +#endif \ No newline at end of file diff --git a/keyboards/planck/keymaps/audio_out/keymap.c b/keyboards/planck/keymaps/audio_out/keymap.c new file mode 100644 index 0000000000..04fc33640d --- /dev/null +++ b/keyboards/planck/keymaps/audio_out/keymap.c @@ -0,0 +1,264 @@ +/* Copyright 2015-2017 Jack Humbert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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 "planck.h" +#include "action_layer.h" + +extern keymap_config_t keymap_config; + +enum planck_layers { + _QWERTY, + _COLEMAK, + _DVORAK, + _LOWER, + _RAISE, + _PLOVER, + _ADJUST +}; + +enum planck_keycodes { + QWERTY = SAFE_RANGE, + COLEMAK, + DVORAK, + PLOVER, + LOWER, + RAISE, + BACKLIT, + EXT_PLV +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* Qwerty + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | S | D | F | G | H | J | K | L | ; | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_QWERTY] = { + {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC}, + {KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT}, + {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT }, + {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT} +}, + +/* Colemak + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | R | S | T | D | H | N | E | I | O | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | K | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_COLEMAK] = { + {KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC}, + {KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT}, + {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT }, + {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT} +}, + +/* Dvorak + * ,-----------------------------------------------------------------------------------. + * | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | O | E | U | I | D | H | T | N | S | / | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_DVORAK] = { + {KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC}, + {KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH}, + {KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT }, + {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT} +}, + +/* Lower + * ,-----------------------------------------------------------------------------------. + * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | Home | End | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_LOWER] = { + {KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC}, + {KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE}, + {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, S(KC_NUHS), S(KC_NUBS), KC_HOME, KC_END, _______}, + {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY} +}, + +/* Raise + * ,-----------------------------------------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / |Pg Up |Pg Dn | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_RAISE] = { + {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC}, + {KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS}, + {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, _______}, + {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY} +}, + +/* Plover layer (http://opensteno.org) + * ,-----------------------------------------------------------------------------------. + * | # | # | # | # | # | # | # | # | # | # | # | # | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | S | T | P | H | * | * | F | P | L | T | D | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | S | K | W | R | * | * | R | B | G | S | Z | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Exit | | | A | O | | E | U | | | | + * `-----------------------------------------------------------------------------------' + */ + +[_PLOVER] = { + {KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1 }, + {XXXXXXX, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC}, + {XXXXXXX, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT}, + {EXT_PLV, XXXXXXX, XXXXXXX, KC_C, KC_V, XXXXXXX, XXXXXXX, KC_N, KC_M, XXXXXXX, XXXXXXX, XXXXXXX} +}, + +/* Adjust (Lower + Raise) + * ,-----------------------------------------------------------------------------------. + * | | Reset| | | | | | | | | | Del | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | + * `-----------------------------------------------------------------------------------' + */ +[_ADJUST] = { + {_______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL }, + {_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______}, + {_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______}, + {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______} +} + + +}; + +#ifdef AUDIO_ENABLE + float plover_song[][2] = SONG(PLOVER_SOUND); + float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND); +#endif + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QWERTY: + if (record->event.pressed) { + print("mode just switched to qwerty and this is a huge string\n"); + set_single_persistent_default_layer(_QWERTY); + } + return false; + break; + case COLEMAK: + if (record->event.pressed) { + set_single_persistent_default_layer(_COLEMAK); + } + return false; + break; + case DVORAK: + if (record->event.pressed) { + set_single_persistent_default_layer(_DVORAK); + } + return false; + break; + case LOWER: + if (record->event.pressed) { + layer_on(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + break; + case RAISE: + if (record->event.pressed) { + layer_on(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + break; + case BACKLIT: + if (record->event.pressed) { + register_code(KC_RSFT); + #ifdef BACKLIGHT_ENABLE + backlight_step(); + #endif + PORTE &= ~(1<<6); + } else { + unregister_code(KC_RSFT); + PORTE |= (1<<6); + } + return false; + break; + case PLOVER: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + stop_all_notes(); + PLAY_SONG(plover_song); + #endif + layer_off(_RAISE); + layer_off(_LOWER); + layer_off(_ADJUST); + layer_on(_PLOVER); + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + keymap_config.raw = eeconfig_read_keymap(); + keymap_config.nkro = 1; + eeconfig_update_keymap(keymap_config.raw); + } + return false; + break; + case EXT_PLV: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_gb_song); + #endif + layer_off(_PLOVER); + } + return false; + break; + } + return true; +} diff --git a/keyboards/planck/keymaps/audio_out/rules.mk b/keyboards/planck/keymaps/audio_out/rules.mk new file mode 100644 index 0000000000..0b2b7ceca5 --- /dev/null +++ b/keyboards/planck/keymaps/audio_out/rules.mk @@ -0,0 +1,3 @@ +AUDIO_ENABLE = yes +BACKLIGHT_ENABLE = no +MIDI_ENABLE = no \ No newline at end of file diff --git a/keyboards/planck/rules.mk b/keyboards/planck/rules.mk index 439f7db645..4d882d0b0b 100644 --- a/keyboards/planck/rules.mk +++ b/keyboards/planck/rules.mk @@ -65,7 +65,7 @@ CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = no # Commands for debug and configuration NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality -MIDI_ENABLE = yes # MIDI controls +MIDI_ENABLE = no # MIDI controls AUDIO_ENABLE = yes # Audio output on port C6 UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID From 7923376de1eff999dc4870dc2709b2dc152cdd04 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 6 Jan 2018 23:52:20 -0500 Subject: [PATCH 3/5] update music functionality --- keyboards/planck/keymaps/audio_out/config.h | 1 + quantum/audio/audio.c | 107 ++++++---- quantum/audio/audio.h | 23 ++- quantum/audio/voices.c | 210 +++++++++++--------- quantum/audio/voices.h | 12 +- quantum/process_keycode/process_audio.c | 4 +- quantum/process_keycode/process_music.c | 2 +- 7 files changed, 212 insertions(+), 147 deletions(-) diff --git a/keyboards/planck/keymaps/audio_out/config.h b/keyboards/planck/keymaps/audio_out/config.h index 83caf12662..b3c5d01d79 100644 --- a/keyboards/planck/keymaps/audio_out/config.h +++ b/keyboards/planck/keymaps/audio_out/config.h @@ -39,6 +39,7 @@ /* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */ //#define MIDI_TONE_KEYCODE_OCTAVES 2 +#define C6_AUDIO #define B7_AUDIO #undef BACKLIGHT_PIN diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 7038d64900..1290a1299f 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -127,7 +127,7 @@ bool playing_note = false; float note_frequency = 0; float note_length = 0; uint8_t note_tempo = TEMPO_DEFAULT; -float note_timbre = TIMBRE_DEFAULT; +float note_timbre[NUMBER_OF_TIMERS] = {TIMBRE_DEFAULT}; uint16_t note_position = 0; float (* notes_pointer)[][2]; uint16_t notes_count; @@ -149,8 +149,8 @@ static bool audio_initialized = false; audio_config_t audio_config; -uint16_t envelope_index = 0; -bool glissando = true; +uint16_t envelope_index[NUMBER_OF_TIMERS] = {0}; +bool glissando[NUMBER_OF_TIMERS] = {true}; #ifndef STARTUP_SONG #define STARTUP_SONG SONG(STARTUP_SOUND) @@ -211,7 +211,7 @@ void audio_init() DISABLE_AUDIO_COUNTER_3_ISR; #endif - #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #ifdef B_AUDIO DISABLE_AUDIO_COUNTER_1_ISR; #endif @@ -223,14 +223,17 @@ void audio_init() #ifdef C6_AUDIO TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); + + TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); + TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre[TIMER_3_INDEX]); #endif - #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #ifdef B_AUDIO TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10); TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre[TIMER_1_INDEX]); #endif audio_initialized = true; @@ -257,7 +260,7 @@ void stop_all_notes() DISABLE_AUDIO_COUNTER_3_OUTPUT; #endif - #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #ifdef B_AUDIO DISABLE_AUDIO_COUNTER_1_ISR; DISABLE_AUDIO_COUNTER_1_OUTPUT; #endif @@ -302,12 +305,18 @@ void stop_note(float freq) if (voice_place >= voices) { voice_place = 0; } + if (voices == 1) { + #if defined(C6_AUDIO) && defined(B_AUDIO) + DISABLE_AUDIO_COUNTER_1_ISR; + DISABLE_AUDIO_COUNTER_1_OUTPUT; + #endif + } if (voices == 0) { #ifdef C6_AUDIO DISABLE_AUDIO_COUNTER_3_ISR; DISABLE_AUDIO_COUNTER_3_OUTPUT; #endif - #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #ifdef B_AUDIO DISABLE_AUDIO_COUNTER_1_ISR; DISABLE_AUDIO_COUNTER_1_OUTPUT; #endif @@ -347,11 +356,11 @@ ISR(TIMER3_COMPA_vect) if (playing_note) { if (voices > 0) { - #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #ifdef B_AUDIO float freq_alt = 0; if (voices > 1) { if (polyphony_rate == 0) { - if (glissando) { + if (glissando[TIMER_1_INDEX] && NUMBER_OF_TIMERS == 1) { if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) { frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2); } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) { @@ -374,18 +383,18 @@ ISR(TIMER3_COMPA_vect) #endif } - if (envelope_index < 65535) { - envelope_index++; + if (envelope_index[TIMER_1_INDEX] < 65535) { + envelope_index[TIMER_1_INDEX]++; } - freq_alt = voice_envelope(freq_alt); + freq_alt = voice_envelope(freq_alt,TIMER_1_INDEX); if (freq_alt < 30.517578125) { freq_alt = 30.52; } TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre[TIMER_1_INDEX]); } #endif @@ -408,7 +417,7 @@ ISR(TIMER3_COMPA_vect) freq = frequencies[voice_place]; #endif } else { - if (glissando) { + if (glissando[TIMER_3_INDEX] && NUMBER_OF_TIMERS == 1) { if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { frequency = frequency * pow(2, 440/frequency/12/2); } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { @@ -431,18 +440,18 @@ ISR(TIMER3_COMPA_vect) #endif } - if (envelope_index < 65535) { - envelope_index++; + if (envelope_index[TIMER_3_INDEX] < 65535) { + envelope_index[TIMER_3_INDEX]++; } - freq = voice_envelope(freq); + freq = voice_envelope(freq, TIMER_3_INDEX); if (freq < 30.517578125) { freq = 30.52; } TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre[TIMER_3_INDEX]); } } @@ -458,13 +467,13 @@ ISR(TIMER3_COMPA_vect) freq = note_frequency; #endif - if (envelope_index < 65535) { - envelope_index++; + if (envelope_index[TIMER_3_INDEX] < 65535) { + envelope_index[TIMER_3_INDEX]++; } - freq = voice_envelope(freq); + freq = voice_envelope(freq, TIMER_3_INDEX); TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre[TIMER_3_INDEX]); } else { TIMER_3_PERIOD = 0; TIMER_3_DUTY_CYCLE = 0; @@ -505,7 +514,7 @@ ISR(TIMER3_COMPA_vect) } } else { note_resting = false; - envelope_index = 0; + envelope_index[TIMER_3_INDEX] = 0; note_frequency = (*notes_pointer)[current_note][0]; note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); } @@ -521,10 +530,16 @@ ISR(TIMER3_COMPA_vect) } #endif -#if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) +#ifdef B_AUDIO +#ifdef B5_AUDIO ISR(TIMER1_COMPA_vect) +#elif defined(B6_AUDIO) +ISR(TIMER1_COMPB_vect) +#elif defined(B7_AUDIO) +ISR(TIMER1_COMPC_vect) +#endif { - #if (defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO)) && !defined(C6_AUDIO) + #if defined(B_AUDIO) && !defined(C6_AUDIO) float freq = 0; if (playing_note) { @@ -548,7 +563,7 @@ ISR(TIMER1_COMPA_vect) freq = frequencies[voice_place]; #endif } else { - if (glissando) { + if (glissando[TIMER_1_INDEX] && NUMBER_OF_TIMERS == 1) { if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { frequency = frequency * pow(2, 440/frequency/12/2); } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { @@ -571,18 +586,18 @@ ISR(TIMER1_COMPA_vect) #endif } - if (envelope_index < 65535) { - envelope_index++; + if (envelope_index[TIMER_1_INDEX] < 65535) { + envelope_index[TIMER_1_INDEX]++; } - freq = voice_envelope(freq); + freq = voice_envelope(freq, TIMER_1_INDEX); if (freq < 30.517578125) { freq = 30.52; } TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre[TIMER_1_INDEX]); } } @@ -598,13 +613,13 @@ ISR(TIMER1_COMPA_vect) freq = note_frequency; #endif - if (envelope_index < 65535) { - envelope_index++; + if (envelope_index[TIMER_1_INDEX] < 65535) { + envelope_index[TIMER_1_INDEX]++; } - freq = voice_envelope(freq); + freq = voice_envelope(freq, TIMER_1_INDEX); TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre[TIMER_1_INDEX]); } else { TIMER_1_PERIOD = 0; TIMER_1_DUTY_CYCLE = 0; @@ -645,7 +660,7 @@ ISR(TIMER1_COMPA_vect) } } else { note_resting = false; - envelope_index = 0; + envelope_index[TIMER_1_INDEX] = 0; note_frequency = (*notes_pointer)[current_note][0]; note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); } @@ -674,7 +689,7 @@ void play_note(float freq, int vol) { #ifdef C6_AUDIO DISABLE_AUDIO_COUNTER_3_ISR; #endif - #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #ifdef B_AUDIO DISABLE_AUDIO_COUNTER_1_ISR; #endif @@ -684,7 +699,6 @@ void play_note(float freq, int vol) { playing_note = true; - envelope_index = 0; if (freq > 0) { frequencies[voices] = freq; @@ -696,16 +710,23 @@ void play_note(float freq, int vol) { ENABLE_AUDIO_COUNTER_3_ISR; ENABLE_AUDIO_COUNTER_3_OUTPUT; #endif - #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + + #ifdef B_AUDIO #ifdef C6_AUDIO if (voices > 1) { + envelope_index[TIMER_3_INDEX] = 0; ENABLE_AUDIO_COUNTER_1_ISR; ENABLE_AUDIO_COUNTER_1_OUTPUT; + } else { + envelope_index[TIMER_3_INDEX] = 0; } #else + envelope_index[TIMER_1_INDEX] = 0; ENABLE_AUDIO_COUNTER_1_ISR; ENABLE_AUDIO_COUNTER_1_OUTPUT; #endif + #else + envelope_index[TIMER_3_INDEX] = 0; #endif } @@ -723,7 +744,7 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) #ifdef C6_AUDIO DISABLE_AUDIO_COUNTER_3_ISR; #endif - #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #ifdef B_AUDIO DISABLE_AUDIO_COUNTER_1_ISR; #endif @@ -749,7 +770,7 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) ENABLE_AUDIO_COUNTER_3_ISR; ENABLE_AUDIO_COUNTER_3_OUTPUT; #endif - #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #ifdef B_AUDIO #ifndef C6_AUDIO ENABLE_AUDIO_COUNTER_1_ISR; ENABLE_AUDIO_COUNTER_1_OUTPUT; @@ -847,8 +868,8 @@ void decrease_polyphony_rate(float change) { // Timbre function -void set_timbre(float timbre) { - note_timbre = timbre; +void set_timbre(float timbre, uint8_t timer_index) { + note_timbre[timer_index] = timbre; } // Tempo functions diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index da09b2bcd2..cbda4e0757 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -36,6 +36,27 @@ // Enable vibrato strength/amplitude - slows down ISR too much // #define VIBRATO_STRENGTH_ENABLE +#ifdef B_AUDIO +#error Please define B5_AUDIO, B6_AUDIO, or B7_AUDIO instead +#endif + +#if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #define B_AUDIO +#endif + +#if defined(C6_AUDIO) && defined (B_AUDIO) + #define NUMBER_OF_TIMERS 2 +#elif defined(C6_AUDIO) + #define NUMBER_OF_TIMERS 1 +#elif defined(B_AUDIO) + #define NUMBER_OF_TIMERS 1 +#else + #define NUMBER_OF_TIMERS 0 +#endif + +#define TIMER_1_INDEX 0 +#define TIMER_3_INDEX 1 + typedef union { uint8_t raw; struct { @@ -75,7 +96,7 @@ void disable_polyphony(void); void increase_polyphony_rate(float change); void decrease_polyphony_rate(float change); -void set_timbre(float timbre); +void set_timbre(float timbre, uint8_t timer_index); void set_tempo(uint8_t tempo); void increase_tempo(uint8_t tempo_change); diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 94147ccb66..1a24902665 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -18,73 +18,91 @@ #include "stdlib.h" // these are imported from audio.c -extern uint16_t envelope_index; -extern float note_timbre; +extern uint16_t envelope_index[NUMBER_OF_TIMERS]; +extern float note_timbre[NUMBER_OF_TIMERS]; extern float polyphony_rate; -extern bool glissando; +extern bool glissando[NUMBER_OF_TIMERS]; -voice_type voice = default_voice; +voice_type voice[NUMBER_OF_TIMERS] = {default_voice}; -void set_voice(voice_type v) { - voice = v; +void set_all_voices(voice_type v) { + for (uint8_t i = 0; i < NUMBER_OF_TIMERS; i++) { + voice[i] = v; + } } -void voice_iterate() { - voice = (voice + 1) % number_of_voices; +void all_voices_iterate(void) { + for (uint8_t i = 0; i < NUMBER_OF_TIMERS; i++) { + voice[i] = (voice[i] + 1) % number_of_voices; + } } -void voice_deiterate() { - voice = (voice - 1 + number_of_voices) % number_of_voices; +void all_voices_deiterate(void) { + for (uint8_t i = 0; i < NUMBER_OF_TIMERS; i++) { + voice[i] = (voice[i] - 1 + number_of_voices) % number_of_voices; + } } -float voice_envelope(float frequency) { - // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz +void set_voice(voice_type v, uint8_t timer_index) { + voice[timer_index] = v; +} + +void voice_iterate(uint8_t timer_index) { + voice[timer_index] = (voice[timer_index] + 1) % number_of_voices; +} + +void voice_deiterate(uint8_t timer_index) { + voice[timer_index] = (voice[timer_index] - 1 + number_of_voices) % number_of_voices; +} + +float voice_envelope(float frequency, uint8_t timer_index) { + // envelope_index[timer_index] ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz __attribute__ ((unused)) - uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); + uint16_t compensated_index = (uint16_t)((float)envelope_index[timer_index] * (880.0 / frequency)); - switch (voice) { + switch (voice[timer_index]) { case default_voice: - glissando = false; - note_timbre = TIMBRE_50; + glissando[timer_index] = false; + note_timbre[timer_index] = TIMBRE_50; polyphony_rate = 0; break; #ifdef AUDIO_VOICES case something: - glissando = false; + glissando[timer_index] = false; polyphony_rate = 0; switch (compensated_index) { case 0 ... 9: - note_timbre = TIMBRE_12; + note_timbre[timer_index] = TIMBRE_12; break; case 10 ... 19: - note_timbre = TIMBRE_25; + note_timbre[timer_index] = TIMBRE_25; break; case 20 ... 200: - note_timbre = .125 + .125; + note_timbre[timer_index] = .125 + .125; break; default: - note_timbre = .125; + note_timbre[timer_index] = .125; break; } break; case drums: - glissando = false; + glissando[timer_index] = false; polyphony_rate = 0; // switch (compensated_index) { // case 0 ... 10: - // note_timbre = 0.5; + // note_timbre[timer_index] = 0.5; // break; // case 11 ... 20: - // note_timbre = 0.5 * (21 - compensated_index) / 10; + // note_timbre[timer_index] = 0.5 * (21 - compensated_index) / 10; // break; // default: - // note_timbre = 0; + // note_timbre[timer_index] = 0; // break; // } // frequency = (rand() % (int)(frequency * 1.2 - frequency)) + (frequency * 0.8); @@ -95,15 +113,15 @@ float voice_envelope(float frequency) { // Bass drum: 60 - 100 Hz frequency = (rand() % (int)(40)) + 60; - switch (envelope_index) { + switch (envelope_index[timer_index]) { case 0 ... 10: - note_timbre = 0.5; + note_timbre[timer_index] = 0.5; break; case 11 ... 20: - note_timbre = 0.5 * (21 - envelope_index) / 10; + note_timbre[timer_index] = 0.5 * (21 - envelope_index[timer_index]) / 10; break; default: - note_timbre = 0; + note_timbre[timer_index] = 0; break; } @@ -112,15 +130,15 @@ float voice_envelope(float frequency) { // Snare drum: 1 - 2 KHz frequency = (rand() % (int)(1000)) + 1000; - switch (envelope_index) { + switch (envelope_index[timer_index]) { case 0 ... 5: - note_timbre = 0.5; + note_timbre[timer_index] = 0.5; break; case 6 ... 20: - note_timbre = 0.5 * (21 - envelope_index) / 15; + note_timbre[timer_index] = 0.5 * (21 - envelope_index[timer_index]) / 15; break; default: - note_timbre = 0; + note_timbre[timer_index] = 0; break; } @@ -128,15 +146,15 @@ float voice_envelope(float frequency) { // Closed Hi-hat: 3 - 5 KHz frequency = (rand() % (int)(2000)) + 3000; - switch (envelope_index) { + switch (envelope_index[timer_index]) { case 0 ... 15: - note_timbre = 0.5; + note_timbre[timer_index] = 0.5; break; case 16 ... 20: - note_timbre = 0.5 * (21 - envelope_index) / 5; + note_timbre[timer_index] = 0.5 * (21 - envelope_index[timer_index]) / 5; break; default: - note_timbre = 0; + note_timbre[timer_index] = 0; break; } @@ -144,96 +162,96 @@ float voice_envelope(float frequency) { // Open Hi-hat: 3 - 5 KHz frequency = (rand() % (int)(2000)) + 3000; - switch (envelope_index) { + switch (envelope_index[timer_index]) { case 0 ... 35: - note_timbre = 0.5; + note_timbre[timer_index] = 0.5; break; case 36 ... 50: - note_timbre = 0.5 * (51 - envelope_index) / 15; + note_timbre[timer_index] = 0.5 * (51 - envelope_index[timer_index]) / 15; break; default: - note_timbre = 0; + note_timbre[timer_index] = 0; break; } } break; case butts_fader: - glissando = true; + glissando[timer_index] = true; polyphony_rate = 0; switch (compensated_index) { case 0 ... 9: frequency = frequency / 4; - note_timbre = TIMBRE_12; + note_timbre[timer_index] = TIMBRE_12; break; case 10 ... 19: frequency = frequency / 2; - note_timbre = TIMBRE_12; + note_timbre[timer_index] = TIMBRE_12; break; case 20 ... 200: - note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; + note_timbre[timer_index] = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; break; default: - note_timbre = 0; + note_timbre[timer_index] = 0; break; } break; - // case octave_crunch: - // polyphony_rate = 0; - // switch (compensated_index) { - // case 0 ... 9: - // case 20 ... 24: - // case 30 ... 32: - // frequency = frequency / 2; - // note_timbre = TIMBRE_12; - // break; + case octave_crunch: + polyphony_rate = 0; + switch (compensated_index) { + case 0 ... 9: + case 20 ... 24: + case 30 ... 32: + frequency = frequency / 2; + note_timbre[timer_index] = TIMBRE_12; + break; - // case 10 ... 19: - // case 25 ... 29: - // case 33 ... 35: - // frequency = frequency * 2; - // note_timbre = TIMBRE_12; - // break; + case 10 ... 19: + case 25 ... 29: + case 33 ... 35: + frequency = frequency * 2; + note_timbre[timer_index] = TIMBRE_12; + break; - // default: - // note_timbre = TIMBRE_12; - // break; - // } - // break; + default: + note_timbre[timer_index] = TIMBRE_12; + break; + } + break; case duty_osc: // This slows the loop down a substantial amount, so higher notes may freeze - glissando = true; + glissando[timer_index] = true; polyphony_rate = 0; switch (compensated_index) { default: #define OCS_SPEED 10 #define OCS_AMP .25 // sine wave is slow - // note_timbre = (sin((float)compensated_index/10000*OCS_SPEED) * OCS_AMP / 2) + .5; + // note_timbre[timer_index] = (sin((float)compensated_index/10000*OCS_SPEED) * OCS_AMP / 2) + .5; // triangle wave is a bit faster - note_timbre = (float)abs((compensated_index*OCS_SPEED % 3000) - 1500) * ( OCS_AMP / 1500 ) + (1 - OCS_AMP) / 2; + note_timbre[timer_index] = (float)abs((compensated_index*OCS_SPEED % 3000) - 1500) * ( OCS_AMP / 1500 ) + (1 - OCS_AMP) / 2; break; } break; case duty_octave_down: - glissando = true; + glissando[timer_index] = true; polyphony_rate = 0; - note_timbre = (envelope_index % 2) * .125 + .375 * 2; - if ((envelope_index % 4) == 0) - note_timbre = 0.5; - if ((envelope_index % 8) == 0) - note_timbre = 0; + note_timbre[timer_index] = (envelope_index[timer_index] % 2) * .125 + .375 * 2; + if ((envelope_index[timer_index] % 4) == 0) + note_timbre[timer_index] = 0.5; + if ((envelope_index[timer_index] % 8) == 0) + note_timbre[timer_index] = 0; break; case delayed_vibrato: - glissando = true; + glissando[timer_index] = true; polyphony_rate = 0; - note_timbre = TIMBRE_50; + note_timbre[timer_index] = TIMBRE_50; #define VOICE_VIBRATO_DELAY 150 #define VOICE_VIBRATO_SPEED 50 switch (compensated_index) { @@ -246,10 +264,10 @@ float voice_envelope(float frequency) { break; // case delayed_vibrato_octave: // polyphony_rate = 0; - // if ((envelope_index % 2) == 1) { - // note_timbre = 0.55; + // if ((envelope_index[timer_index] % 2) == 1) { + // note_timbre[timer_index] = 0.55; // } else { - // note_timbre = 0.45; + // note_timbre[timer_index] = 0.45; // } // #define VOICE_VIBRATO_DELAY 150 // #define VOICE_VIBRATO_SPEED 50 @@ -262,28 +280,28 @@ float voice_envelope(float frequency) { // } // break; // case duty_fifth_down: - // note_timbre = 0.5; - // if ((envelope_index % 3) == 0) - // note_timbre = 0.75; + // note_timbre[timer_index] = 0.5; + // if ((envelope_index[timer_index] % 3) == 0) + // note_timbre[timer_index] = 0.75; // break; // case duty_fourth_down: - // note_timbre = 0.0; - // if ((envelope_index % 12) == 0) - // note_timbre = 0.75; - // if (((envelope_index % 12) % 4) != 1) - // note_timbre = 0.75; + // note_timbre[timer_index] = 0.0; + // if ((envelope_index[timer_index] % 12) == 0) + // note_timbre[timer_index] = 0.75; + // if (((envelope_index[timer_index] % 12) % 4) != 1) + // note_timbre[timer_index] = 0.75; // break; // case duty_third_down: - // note_timbre = 0.5; - // if ((envelope_index % 5) == 0) - // note_timbre = 0.75; + // note_timbre[timer_index] = 0.5; + // if ((envelope_index[timer_index] % 5) == 0) + // note_timbre[timer_index] = 0.75; // break; // case duty_fifth_third_down: - // note_timbre = 0.5; - // if ((envelope_index % 5) == 0) - // note_timbre = 0.75; - // if ((envelope_index % 3) == 0) - // note_timbre = 0.25; + // note_timbre[timer_index] = 0.5; + // if ((envelope_index[timer_index] % 5) == 0) + // note_timbre[timer_index] = 0.75; + // if ((envelope_index[timer_index] % 3) == 0) + // note_timbre[timer_index] = 0.25; // break; #endif diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 1cf33095a4..a47ec4f387 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -24,7 +24,7 @@ #ifndef VOICES_H #define VOICES_H -float voice_envelope(float frequency); +float voice_envelope(float frequency, uint8_t timer_index); typedef enum { default_voice, @@ -45,8 +45,12 @@ typedef enum { number_of_voices // important that this is last } voice_type; -void set_voice(voice_type v); -void voice_iterate(void); -void voice_deiterate(void); +void set_all_voices(voice_type v); +void all_voices_iterate(void); +void all_voices_deiterate(void); + +void set_voice(voice_type v, uint8_t timer_index); +void voice_iterate(uint8_t timer_index); +void voice_deiterate(uint8_t timer_index); #endif diff --git a/quantum/process_keycode/process_audio.c b/quantum/process_keycode/process_audio.c index 32057ae8dc..69a8a11152 100644 --- a/quantum/process_keycode/process_audio.c +++ b/quantum/process_keycode/process_audio.c @@ -38,13 +38,13 @@ bool process_audio(uint16_t keycode, keyrecord_t *record) { } if (keycode == MUV_IN && record->event.pressed) { - voice_iterate(); + all_voices_iterate(); PLAY_SONG(voice_change_song); return false; } if (keycode == MUV_DE && record->event.pressed) { - voice_deiterate(); + all_voices_deiterate(); PLAY_SONG(voice_change_song); return false; } diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c index c7f41cc388..b0ae1151c9 100644 --- a/quantum/process_keycode/process_music.c +++ b/quantum/process_keycode/process_music.c @@ -28,7 +28,7 @@ bool music_activated = false; bool midi_activated = false; uint8_t music_starting_note = 0x0C; int music_offset = 7; -uint8_t music_mode = MUSIC_MODE_CHROMATIC; +uint8_t music_mode = MUSIC_MODE_MAJOR; // music sequencer static bool music_sequence_recording = false; From 690a08cbbbf41300214d9b74daffbbccefab4a87 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 15 Jan 2018 16:06:49 -0500 Subject: [PATCH 4/5] fix up arm audio implementation --- quantum/audio/audio_arm.c | 223 ++++++++++++++++++++++++++++++-------- 1 file changed, 178 insertions(+), 45 deletions(-) diff --git a/quantum/audio/audio_arm.c b/quantum/audio/audio_arm.c index 43c8d67c48..6f8b5e3078 100644 --- a/quantum/audio/audio_arm.c +++ b/quantum/audio/audio_arm.c @@ -77,23 +77,48 @@ bool glissando = true; #endif float startup_song[][2] = STARTUP_SONG; -static void gpt_cb6(GPTDriver *gptp); -static void gpt_cb7(GPTDriver *gptp); static void gpt_cb8(GPTDriver *gptp); +#define DAC_BUFFER_SIZE 360 + +#define START_CHANNEL_1() gptStart(&GPTD6, &gpt6cfg1); \ + gptStartContinuous(&GPTD6, 2U) +#define START_CHANNEL_2() gptStart(&GPTD7, &gpt7cfg1); \ + gptStartContinuous(&GPTD7, 2U) +#define STOP_CHANNEL_1() gptStopTimer(&GPTD6) +#define STOP_CHANNEL_2() gptStopTimer(&GPTD7) +#define RESTART_CHANNEL_1() STOP_CHANNEL_1(); \ + START_CHANNEL_1() +#define RESTART_CHANNEL_2() STOP_CHANNEL_1(); \ + START_CHANNEL_1() +#define UPDATE_CHANNEL_1_FREQ(freq) gpt6cfg1.frequency = freq * DAC_BUFFER_SIZE; \ + RESTART_CHANNEL_1() +#define UPDATE_CHANNEL_2_FREQ(freq) gpt7cfg1.frequency = freq * DAC_BUFFER_SIZE; \ + RESTART_CHANNEL_2() +#define GET_CHANNEL_1_FREQ gpt6cfg1.frequency +#define GET_CHANNEL_2_FREQ gpt7cfg1.frequency + + /* * GPT6 configuration. */ +// static const GPTConfig gpt6cfg1 = { +// .frequency = 1000000U, +// .callback = NULL, +// .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ +// .dier = 0U +// }; + GPTConfig gpt6cfg1 = { - .frequency = 440, - .callback = gpt_cb6, + .frequency = 440U*DAC_BUFFER_SIZE, + .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U }; GPTConfig gpt7cfg1 = { - .frequency = 440, - .callback = gpt_cb7, + .frequency = 440U*DAC_BUFFER_SIZE, + .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U }; @@ -105,15 +130,122 @@ GPTConfig gpt8cfg1 = { .dier = 0U }; -static void gpt_cb6(GPTDriver *gptp) { - palTogglePad(GPIOA, 4); + +/* + * DAC test buffer (sine wave). + */ +// static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = { +// 2047, 2082, 2118, 2154, 2189, 2225, 2260, 2296, 2331, 2367, 2402, 2437, +// 2472, 2507, 2542, 2576, 2611, 2645, 2679, 2713, 2747, 2780, 2813, 2846, +// 2879, 2912, 2944, 2976, 3008, 3039, 3070, 3101, 3131, 3161, 3191, 3221, +// 3250, 3278, 3307, 3335, 3362, 3389, 3416, 3443, 3468, 3494, 3519, 3544, +// 3568, 3591, 3615, 3637, 3660, 3681, 3703, 3723, 3744, 3763, 3782, 3801, +// 3819, 3837, 3854, 3870, 3886, 3902, 3917, 3931, 3944, 3958, 3970, 3982, +// 3993, 4004, 4014, 4024, 4033, 4041, 4049, 4056, 4062, 4068, 4074, 4078, +// 4082, 4086, 4089, 4091, 4092, 4093, 4094, 4093, 4092, 4091, 4089, 4086, +// 4082, 4078, 4074, 4068, 4062, 4056, 4049, 4041, 4033, 4024, 4014, 4004, +// 3993, 3982, 3970, 3958, 3944, 3931, 3917, 3902, 3886, 3870, 3854, 3837, +// 3819, 3801, 3782, 3763, 3744, 3723, 3703, 3681, 3660, 3637, 3615, 3591, +// 3568, 3544, 3519, 3494, 3468, 3443, 3416, 3389, 3362, 3335, 3307, 3278, +// 3250, 3221, 3191, 3161, 3131, 3101, 3070, 3039, 3008, 2976, 2944, 2912, +// 2879, 2846, 2813, 2780, 2747, 2713, 2679, 2645, 2611, 2576, 2542, 2507, +// 2472, 2437, 2402, 2367, 2331, 2296, 2260, 2225, 2189, 2154, 2118, 2082, +// 2047, 2012, 1976, 1940, 1905, 1869, 1834, 1798, 1763, 1727, 1692, 1657, +// 1622, 1587, 1552, 1518, 1483, 1449, 1415, 1381, 1347, 1314, 1281, 1248, +// 1215, 1182, 1150, 1118, 1086, 1055, 1024, 993, 963, 933, 903, 873, +// 844, 816, 787, 759, 732, 705, 678, 651, 626, 600, 575, 550, +// 526, 503, 479, 457, 434, 413, 391, 371, 350, 331, 312, 293, +// 275, 257, 240, 224, 208, 192, 177, 163, 150, 136, 124, 112, +// 101, 90, 80, 70, 61, 53, 45, 38, 32, 26, 20, 16, +// 12, 8, 5, 3, 2, 1, 0, 1, 2, 3, 5, 8, +// 12, 16, 20, 26, 32, 38, 45, 53, 61, 70, 80, 90, +// 101, 112, 124, 136, 150, 163, 177, 192, 208, 224, 240, 257, +// 275, 293, 312, 331, 350, 371, 391, 413, 434, 457, 479, 503, +// 526, 550, 575, 600, 626, 651, 678, 705, 732, 759, 787, 816, +// 844, 873, 903, 933, 963, 993, 1024, 1055, 1086, 1118, 1150, 1182, +// 1215, 1248, 1281, 1314, 1347, 1381, 1415, 1449, 1483, 1518, 1552, 1587, +// 1622, 1657, 1692, 1727, 1763, 1798, 1834, 1869, 1905, 1940, 1976, 2012 +// }; + +// squarewave +static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = { + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * DAC streaming callback. + */ +size_t nx = 0, ny = 0, nz = 0; +static void end_cb1(DACDriver *dacp, const dacsample_t *buffer, size_t n) { + + (void)dacp; + + nz++; + if (dac_buffer == buffer) { + nx += n; + } + else { + ny += n; + } + + if ((nz % 1000) == 0) { + // palTogglePad(GPIOD, GPIOD_LED3); + } } +/* + * DAC error callback. + */ +static void error_cb1(DACDriver *dacp, dacerror_t err) { -static void gpt_cb7(GPTDriver *gptp) { - palTogglePad(GPIOA, 5); + (void)dacp; + (void)err; + + chSysHalt("DAC failure"); } +static const DACConfig dac1cfg1 = { + .init = 2047U, + .datamode = DAC_DHRM_12BIT_RIGHT +}; + +static const DACConversionGroup dacgrpcfg1 = { + .num_channels = 1U, + .end_cb = end_cb1, + .error_cb = error_cb1, + .trigger = DAC_TRG(0) +}; + void audio_init() { @@ -128,8 +260,27 @@ void audio_init() // audio_config.raw = eeconfig_read_audio(); audio_config.enable = true; - palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); + /* + * Starting DAC1 driver, setting up the output pin as analog as suggested + * by the Reference Manual. + */ + palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); + dacStart(&DACD1, &dac1cfg1); + + /* + * Starting GPT6 driver, it is used for triggering the DAC. + */ + START_CHANNEL_1(); + START_CHANNEL_2(); + + /* + * Starting a continuous conversion. + */ + dacStartConversion(&DACD1, &dacgrpcfg1, + (dacsample_t *)dac_buffer, DAC_BUFFER_SIZE); + // gptStartContinuous(&GPTD6, 2U); + audio_initialized = true; @@ -193,8 +344,8 @@ void stop_note(float freq) voice_place = 0; } if (voices == 0) { - gptStopTimer(&GPTD6); - gptStopTimer(&GPTD7); + STOP_CHANNEL_1(); + STOP_CHANNEL_2(); gptStopTimer(&GPTD8); frequency = 0; frequency_alt = 0; @@ -224,20 +375,6 @@ float vibrato(float average_freq) { #endif -static void restart_gpt6(void) { - // gptStopTimer(&GPTD6); - - gptStart(&GPTD6, &gpt6cfg1); - gptStartContinuous(&GPTD6, 2U); -} - -static void restart_gpt7(void) { - // gptStopTimer(&GPTD7); - - gptStart(&GPTD7, &gpt7cfg1); - gptStartContinuous(&GPTD7, 2U); -} - static void gpt_cb8(GPTDriver *gptp) { float freq; @@ -280,13 +417,12 @@ static void gpt_cb8(GPTDriver *gptp) { freq_alt = 30.52; } - if (gpt6cfg1.frequency != (uint16_t)freq_alt) { - gpt6cfg1.frequency = freq_alt; - restart_gpt6(); + if (GET_CHANNEL_1_FREQ != (uint16_t)freq_alt) { + UPDATE_CHANNEL_1_FREQ(freq_alt); } //note_timbre; } else { - // gptStopTimer(&GPTD6); + STOP_CHANNEL_1(); } if (polyphony_rate > 0) { @@ -342,9 +478,8 @@ static void gpt_cb8(GPTDriver *gptp) { } - if (gpt7cfg1.frequency != (uint16_t)freq) { - gpt7cfg1.frequency = freq; - restart_gpt7(); + if (GET_CHANNEL_2_FREQ != (uint16_t)freq) { + UPDATE_CHANNEL_2_FREQ(freq); } //note_timbre; } else { @@ -370,11 +505,9 @@ static void gpt_cb8(GPTDriver *gptp) { freq = voice_envelope(freq); - if (gpt6cfg1.frequency != (uint16_t)freq) { - gpt6cfg1.frequency = freq; - restart_gpt6(); - gpt7cfg1.frequency = freq; - restart_gpt7(); + if (GET_CHANNEL_1_FREQ != (uint16_t)freq) { + UPDATE_CHANNEL_1_FREQ(freq); + UPDATE_CHANNEL_2_FREQ(freq); } //note_timbre; } else { @@ -384,7 +517,7 @@ static void gpt_cb8(GPTDriver *gptp) { note_position++; bool end_of_note = false; - if (gpt6cfg1.frequency > 0) { + if (GET_CHANNEL_1_FREQ > 0) { if (!note_resting) end_of_note = (note_position >= (note_length*16 - 1)); else @@ -399,8 +532,8 @@ static void gpt_cb8(GPTDriver *gptp) { if (notes_repeat) { current_note = 0; } else { - gptStopTimer(&GPTD6); - gptStopTimer(&GPTD7); + STOP_CHANNEL_1(); + STOP_CHANNEL_2(); // gptStopTimer(&GPTD8); playing_notes = false; return; @@ -492,8 +625,8 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) gptStart(&GPTD8, &gpt8cfg1); gptStartContinuous(&GPTD8, 2U); - restart_gpt6(); - restart_gpt7(); + RESTART_CHANNEL_1(); + RESTART_CHANNEL_2(); } } From ad982e39d6bc5387a62a0fa684392368cc00f14b Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 15 Jan 2018 23:21:28 -0500 Subject: [PATCH 5/5] implement new features for arm --- quantum/audio/audio.h | 15 +++++++++++++++ quantum/audio/audio_arm.c | 37 +++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index cbda4e0757..1636052106 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -36,6 +36,10 @@ // Enable vibrato strength/amplitude - slows down ISR too much // #define VIBRATO_STRENGTH_ENABLE +#if defined(__AVR__) + +// avr + #ifdef B_AUDIO #error Please define B5_AUDIO, B6_AUDIO, or B7_AUDIO instead #endif @@ -57,6 +61,17 @@ #define TIMER_1_INDEX 0 #define TIMER_3_INDEX 1 +#else + +// chibios + +#define NUMBER_OF_TIMERS 2 + +#define TIMER_6_INDEX 0 +#define TIMER_7_INDEX 1 + +#endif + typedef union { uint8_t raw; struct { diff --git a/quantum/audio/audio_arm.c b/quantum/audio/audio_arm.c index 6f8b5e3078..acc796f086 100644 --- a/quantum/audio/audio_arm.c +++ b/quantum/audio/audio_arm.c @@ -47,7 +47,7 @@ bool playing_note = false; float note_frequency = 0; float note_length = 0; uint8_t note_tempo = TEMPO_DEFAULT; -float note_timbre = TIMBRE_DEFAULT; +float note_timbre[NUMBER_OF_TIMERS] = {TIMBRE_DEFAULT}; uint16_t note_position = 0; float (* notes_pointer)[][2]; uint16_t notes_count; @@ -69,8 +69,8 @@ static bool audio_initialized = false; audio_config_t audio_config; -uint16_t envelope_index = 0; -bool glissando = true; +uint16_t envelope_index[NUMBER_OF_TIMERS] = {0}; +bool glissando[NUMBER_OF_TIMERS] = {true}; #ifndef STARTUP_SONG #define STARTUP_SONG SONG(STARTUP_SOUND) @@ -384,7 +384,7 @@ static void gpt_cb8(GPTDriver *gptp) { float freq_alt = 0; if (voices > 1) { if (polyphony_rate == 0) { - if (glissando) { + if (glissando[TIMER_6_INDEX]) { if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) { frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2); } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) { @@ -407,11 +407,11 @@ static void gpt_cb8(GPTDriver *gptp) { #endif } - if (envelope_index < 65535) { - envelope_index++; + if (envelope_index[TIMER_6_INDEX] < 65535) { + envelope_index[TIMER_6_INDEX]++; } - freq_alt = voice_envelope(freq_alt); + freq_alt = voice_envelope(freq_alt, TIMER_6_INDEX); if (freq_alt < 30.517578125) { freq_alt = 30.52; @@ -444,7 +444,7 @@ static void gpt_cb8(GPTDriver *gptp) { freq = frequencies[voice_place]; #endif } else { - if (glissando) { + if (glissando[TIMER_7_INDEX]) { if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { frequency = frequency * pow(2, 440/frequency/12/2); } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { @@ -467,11 +467,11 @@ static void gpt_cb8(GPTDriver *gptp) { #endif } - if (envelope_index < 65535) { - envelope_index++; + if (envelope_index[TIMER_7_INDEX] < 65535) { + envelope_index[TIMER_7_INDEX]++; } - freq = voice_envelope(freq); + freq = voice_envelope(freq, TIMER_7_INDEX); if (freq < 30.517578125) { freq = 30.52; @@ -499,10 +499,10 @@ static void gpt_cb8(GPTDriver *gptp) { freq = note_frequency; #endif - if (envelope_index < 65535) { - envelope_index++; + if (envelope_index[TIMER_6_INDEX] < 65535) { + envelope_index[TIMER_6_INDEX]++; } - freq = voice_envelope(freq); + freq = voice_envelope(freq, TIMER_6_INDEX); if (GET_CHANNEL_1_FREQ != (uint16_t)freq) { @@ -551,7 +551,7 @@ static void gpt_cb8(GPTDriver *gptp) { } } else { note_resting = false; - envelope_index = 0; + envelope_index[TIMER_6_INDEX] = 0; note_frequency = (*notes_pointer)[current_note][0]; note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); } @@ -582,7 +582,8 @@ void play_note(float freq, int vol) { playing_note = true; - envelope_index = 0; + envelope_index[TIMER_6_INDEX] = 0; + envelope_index[TIMER_7_INDEX] = 0; if (freq > 0) { frequencies[voices] = freq; @@ -715,8 +716,8 @@ void decrease_polyphony_rate(float change) { // Timbre function -void set_timbre(float timbre) { - note_timbre = timbre; +void set_timbre(float timbre, uint8_t timer_index) { + note_timbre[timer_index] = timbre; } // Tempo functions