forked from mfulz_github/qmk_firmware
Compare commits
10 Commits
master
...
arm-dac-wo
Author | SHA1 | Date |
---|---|---|
Jack Humbert | f52faeb5d6 | |
Jack Humbert | bfe468ef1d | |
Jack Humbert | 474d100b56 | |
Jack Humbert | 208bee10f2 | |
Jack Humbert | 3e6478b0bb | |
Jack Humbert | 3e1826a332 | |
Jack Humbert | 73853d651a | |
Jack Humbert | dfb401b950 | |
Jack Humbert | 9632b3379f | |
Jack Humbert | 6241f3f3b7 |
|
@ -51,6 +51,9 @@
|
||||||
#undef AUDIO_VOICES
|
#undef AUDIO_VOICES
|
||||||
#undef C6_AUDIO
|
#undef C6_AUDIO
|
||||||
|
|
||||||
|
#define A5_AUDIO
|
||||||
|
#define DAC_OFF_VALUE 4095
|
||||||
|
|
||||||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
||||||
#define DEBOUNCE 6
|
#define DEBOUNCE 6
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
// Most tactile encoders have detents every 4 stages
|
||||||
|
#define ENCODER_RESOLUTION 4
|
||||||
|
|
|
@ -0,0 +1,298 @@
|
||||||
|
/* Copyright 2019 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include QMK_KEYBOARD_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,
|
||||||
|
BACKLIT,
|
||||||
|
EXT_PLV
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LOWER MO(_LOWER)
|
||||||
|
#define RAISE MO(_RAISE)
|
||||||
|
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
_______, 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
|
||||||
|
|
||||||
|
uint32_t layer_state_set_user(uint32_t state) {
|
||||||
|
return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 BACKLIT:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
register_code(KC_RSFT);
|
||||||
|
#ifdef BACKLIGHT_ENABLE
|
||||||
|
backlight_step();
|
||||||
|
#endif
|
||||||
|
#ifdef KEYBOARD_planck_rev5
|
||||||
|
PORTE &= ~(1<<6);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
unregister_code(KC_RSFT);
|
||||||
|
#ifdef KEYBOARD_planck_rev5
|
||||||
|
PORTE |= (1<<6);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void encoder_update(bool clockwise) {
|
||||||
|
if (clockwise) {
|
||||||
|
#ifdef MOUSEKEY_ENABLE
|
||||||
|
register_code(KC_MS_WH_DOWN);
|
||||||
|
unregister_code(KC_MS_WH_DOWN);
|
||||||
|
#else
|
||||||
|
register_code(KC_PGDN);
|
||||||
|
unregister_code(KC_PGDN);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifdef MOUSEKEY_ENABLE
|
||||||
|
register_code(KC_MS_WH_UP);
|
||||||
|
unregister_code(KC_MS_WH_UP);
|
||||||
|
#else
|
||||||
|
register_code(KC_PGUP);
|
||||||
|
unregister_code(KC_PGUP);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void matrix_scan_user(void) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool music_mask_user(uint16_t keycode) {
|
||||||
|
switch (keycode) {
|
||||||
|
case RAISE:
|
||||||
|
case LOWER:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "sample.h"
|
||||||
|
|
||||||
|
uint32_t dac_sample_custom_counter = 0;
|
||||||
|
|
||||||
|
uint16_t dac_value_generate(void) {
|
||||||
|
if (is_playing_note()) {
|
||||||
|
uint16_t sample = dac_sample_custom[dac_sample_custom_counter];
|
||||||
|
dac_sample_custom_counter = (dac_sample_custom_counter + 1) % DAC_SAMPLE_CUSTOM_LENGTH;
|
||||||
|
return sample;
|
||||||
|
} else {
|
||||||
|
return DAC_OFF_VALUE;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,39 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
// Most tactile encoders have detents every 4 stages
|
||||||
|
#define ENCODER_RESOLUTION 4
|
||||||
|
|
|
@ -0,0 +1,326 @@
|
||||||
|
/* Copyright 2019 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include QMK_KEYBOARD_H
|
||||||
|
#include "audio.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,
|
||||||
|
BACKLIT,
|
||||||
|
EXT_PLV
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LOWER MO(_LOWER)
|
||||||
|
#define RAISE MO(_RAISE)
|
||||||
|
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
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] = LAYOUT_planck_grid(
|
||||||
|
_______, 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
|
||||||
|
|
||||||
|
uint32_t layer_state_set_user(uint32_t state) {
|
||||||
|
return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 BACKLIT:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
register_code(KC_RSFT);
|
||||||
|
#ifdef BACKLIGHT_ENABLE
|
||||||
|
backlight_step();
|
||||||
|
#endif
|
||||||
|
#ifdef KEYBOARD_planck_rev5
|
||||||
|
PORTE &= ~(1<<6);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
unregister_code(KC_RSFT);
|
||||||
|
#ifdef KEYBOARD_planck_rev5
|
||||||
|
PORTE |= (1<<6);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void matrix_scan_user(void) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool music_mask_user(uint16_t keycode) {
|
||||||
|
switch (keycode) {
|
||||||
|
case RAISE:
|
||||||
|
case LOWER:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "wavetable.h"
|
||||||
|
|
||||||
|
float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
|
||||||
|
uint8_t dac_morph = 0;
|
||||||
|
// uint8_t dac_morph_flipped = 0;
|
||||||
|
// uint16_t dac_morph_counter = 0;
|
||||||
|
|
||||||
|
void dac_setup_note(void) {
|
||||||
|
dac_if[dac_number_of_voices()] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t dac_value_generate(void) {
|
||||||
|
uint16_t value = DAC_OFF_VALUE;
|
||||||
|
uint8_t working_voices = dac_number_of_voices();
|
||||||
|
if (working_voices > DAC_VOICES_MAX)
|
||||||
|
working_voices = DAC_VOICES_MAX;
|
||||||
|
|
||||||
|
if (working_voices > 0) {
|
||||||
|
uint16_t value_avg = 0;
|
||||||
|
for (uint8_t i = 0; i < working_voices; i++) {
|
||||||
|
dac_if[i] = dac_if[i] + ((dac_get_frequency(i) * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE);
|
||||||
|
|
||||||
|
// Needed because % doesn't work with floats
|
||||||
|
while (dac_if[i] >= (DAC_BUFFER_SIZE))
|
||||||
|
dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE;
|
||||||
|
|
||||||
|
// #define DAC_MORPH_SPEED 372
|
||||||
|
// #define DAC_MORPH_SPEED_COMPUTED (DAC_SAMPLE_RATE / DAC_WAVETABLE_CUSTOM_LENGTH * (1000 / DAC_MORPH_SPEED))
|
||||||
|
|
||||||
|
uint16_t dac_i = (uint16_t)dac_if[i];
|
||||||
|
// value_avg += dac_buffer_custom[dac_morph_flipped][dac_i] / working_voices / 2 * ((dac_morph >= 63) ? 6400 - dac_morph_counter : dac_morph_counter) / 6400;
|
||||||
|
// value_avg += dac_buffer_custom[dac_morph_flipped + 1][dac_i] / working_voices / 2 * ((dac_morph >= 63) ? dac_morph_counter : 6400 - dac_morph_counter) / 6400;
|
||||||
|
|
||||||
|
// value_avg += dac_wavetable_custom[dac_morph][dac_i] / working_voices / 2 * (DAC_MORPH_SPEED_COMPUTED - dac_morph_counter) / DAC_MORPH_SPEED_COMPUTED;
|
||||||
|
// value_avg += dac_wavetable_custom[dac_morph + 1][dac_i] / working_voices / 2 * dac_morph_counter / DAC_MORPH_SPEED_COMPUTED;
|
||||||
|
value_avg += dac_wavetable_custom[dac_morph][dac_i] / working_voices;
|
||||||
|
}
|
||||||
|
value = value_avg;
|
||||||
|
|
||||||
|
// dac_morph_counter++;
|
||||||
|
// if (dac_morph_counter >= DAC_MORPH_SPEED_COMPUTED) {
|
||||||
|
// dac_morph_counter = 0;
|
||||||
|
// dac_morph = (dac_morph + 1) % 125;
|
||||||
|
// dac_morph_flipped = ((dac_morph >= 63) ? (125 - dac_morph) : dac_morph);
|
||||||
|
// dac_morph = (dac_morph + 1) % (DAC_WAVETABLE_CUSTOM_LENGTH - 1);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void encoder_update(bool clockwise) {
|
||||||
|
if (clockwise) {
|
||||||
|
dac_morph = (dac_morph + 1) % DAC_WAVETABLE_CUSTOM_LENGTH;
|
||||||
|
} else {
|
||||||
|
if (dac_morph == 0)
|
||||||
|
dac_morph = (DAC_WAVETABLE_CUSTOM_LENGTH - 1);
|
||||||
|
else
|
||||||
|
dac_morph--;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -51,6 +51,8 @@
|
||||||
#undef AUDIO_VOICES
|
#undef AUDIO_VOICES
|
||||||
#undef C6_AUDIO
|
#undef C6_AUDIO
|
||||||
|
|
||||||
|
#define A5_AUDIO
|
||||||
|
|
||||||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
||||||
#define DEBOUNCE 6
|
#define DEBOUNCE 6
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,9 @@
|
||||||
#include "rev6.h"
|
#include "rev6.h"
|
||||||
|
|
||||||
void matrix_init_kb(void) {
|
void matrix_init_kb(void) {
|
||||||
matrix_init_user();
|
palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL );
|
||||||
|
palSetPad(GPIOA, 4);
|
||||||
|
matrix_init_user();
|
||||||
}
|
}
|
||||||
|
|
||||||
void matrix_scan_kb(void) {
|
void matrix_scan_kb(void) {
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#ifndef AUDIO_H
|
|
||||||
#define AUDIO_H
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -27,6 +27,9 @@
|
||||||
#include "voices.h"
|
#include "voices.h"
|
||||||
#include "quantum.h"
|
#include "quantum.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#if defined(PROTOCOL_CHIBIOS)
|
||||||
|
#include "audio_arm.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Largely untested PWM audio mode (doesn't sound as good)
|
// Largely untested PWM audio mode (doesn't sound as good)
|
||||||
// #define PWM_AUDIO
|
// #define PWM_AUDIO
|
||||||
|
@ -107,6 +110,5 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat);
|
||||||
#define PLAY_SONG(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), false)
|
#define PLAY_SONG(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), false)
|
||||||
#define PLAY_LOOP(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), true)
|
#define PLAY_LOOP(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), true)
|
||||||
|
|
||||||
|
bool is_playing_note(void);
|
||||||
bool is_playing_notes(void);
|
bool is_playing_notes(void);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright 2016 Jack Humbert
|
/* Copyright 2016-2019 Jack Humbert
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -26,21 +26,8 @@
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
int voices = 0;
|
uint8_t dac_voices = 0;
|
||||||
int voice_place = 0;
|
float dac_frequencies[8] = { 0.0 };
|
||||||
float frequency = 0;
|
|
||||||
float frequency_alt = 0;
|
|
||||||
int volume = 0;
|
|
||||||
long position = 0;
|
|
||||||
|
|
||||||
float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
|
||||||
int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
|
||||||
bool sliding = false;
|
|
||||||
|
|
||||||
float place = 0;
|
|
||||||
|
|
||||||
uint8_t * sample;
|
|
||||||
uint16_t sample_length = 0;
|
|
||||||
|
|
||||||
bool playing_notes = false;
|
bool playing_notes = false;
|
||||||
bool playing_note = false;
|
bool playing_note = false;
|
||||||
|
@ -48,14 +35,12 @@ float note_frequency = 0;
|
||||||
float note_length = 0;
|
float note_length = 0;
|
||||||
uint8_t note_tempo = TEMPO_DEFAULT;
|
uint8_t note_tempo = TEMPO_DEFAULT;
|
||||||
float note_timbre = TIMBRE_DEFAULT;
|
float note_timbre = TIMBRE_DEFAULT;
|
||||||
uint16_t note_position = 0;
|
uint32_t note_position = 0;
|
||||||
float (* notes_pointer)[][2];
|
float (* notes_pointer)[][2];
|
||||||
uint16_t notes_count;
|
uint16_t notes_count;
|
||||||
bool notes_repeat;
|
bool notes_repeat;
|
||||||
bool note_resting = false;
|
|
||||||
|
|
||||||
uint16_t current_note = 0;
|
uint16_t current_note = 0;
|
||||||
uint8_t rest_counter = 0;
|
|
||||||
|
|
||||||
#ifdef VIBRATO_ENABLE
|
#ifdef VIBRATO_ENABLE
|
||||||
float vibrato_counter = 0;
|
float vibrato_counter = 0;
|
||||||
|
@ -77,200 +62,198 @@ bool glissando = true;
|
||||||
#endif
|
#endif
|
||||||
float startup_song[][2] = STARTUP_SONG;
|
float startup_song[][2] = STARTUP_SONG;
|
||||||
|
|
||||||
static void gpt_cb8(GPTDriver *gptp);
|
static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = {
|
||||||
|
// 256 values, max 4095
|
||||||
#define DAC_BUFFER_SIZE 100
|
0x800,0x832,0x864,0x896,0x8c8,0x8fa,0x92c,0x95e,
|
||||||
#ifndef DAC_SAMPLE_MAX
|
0x98f,0x9c0,0x9f1,0xa22,0xa52,0xa82,0xab1,0xae0,
|
||||||
#define DAC_SAMPLE_MAX 65535U
|
0xb0f,0xb3d,0xb6b,0xb98,0xbc5,0xbf1,0xc1c,0xc47,
|
||||||
#endif
|
0xc71,0xc9a,0xcc3,0xceb,0xd12,0xd39,0xd5f,0xd83,
|
||||||
|
0xda7,0xdca,0xded,0xe0e,0xe2e,0xe4e,0xe6c,0xe8a,
|
||||||
#define START_CHANNEL_1() gptStart(&GPTD6, &gpt6cfg1); \
|
0xea6,0xec1,0xedc,0xef5,0xf0d,0xf24,0xf3a,0xf4f,
|
||||||
gptStartContinuous(&GPTD6, 2U)
|
0xf63,0xf76,0xf87,0xf98,0xfa7,0xfb5,0xfc2,0xfcd,
|
||||||
#define START_CHANNEL_2() gptStart(&GPTD7, &gpt7cfg1); \
|
0xfd8,0xfe1,0xfe9,0xff0,0xff5,0xff9,0xffd,0xffe,
|
||||||
gptStartContinuous(&GPTD7, 2U)
|
0xfff,0xffe,0xffd,0xff9,0xff5,0xff0,0xfe9,0xfe1,
|
||||||
#define STOP_CHANNEL_1() gptStopTimer(&GPTD6)
|
0xfd8,0xfcd,0xfc2,0xfb5,0xfa7,0xf98,0xf87,0xf76,
|
||||||
#define STOP_CHANNEL_2() gptStopTimer(&GPTD7)
|
0xf63,0xf4f,0xf3a,0xf24,0xf0d,0xef5,0xedc,0xec1,
|
||||||
#define RESTART_CHANNEL_1() STOP_CHANNEL_1(); \
|
0xea6,0xe8a,0xe6c,0xe4e,0xe2e,0xe0e,0xded,0xdca,
|
||||||
START_CHANNEL_1()
|
0xda7,0xd83,0xd5f,0xd39,0xd12,0xceb,0xcc3,0xc9a,
|
||||||
#define RESTART_CHANNEL_2() STOP_CHANNEL_2(); \
|
0xc71,0xc47,0xc1c,0xbf1,0xbc5,0xb98,0xb6b,0xb3d,
|
||||||
START_CHANNEL_2()
|
0xb0f,0xae0,0xab1,0xa82,0xa52,0xa22,0x9f1,0x9c0,
|
||||||
#define UPDATE_CHANNEL_1_FREQ(freq) gpt6cfg1.frequency = freq * DAC_BUFFER_SIZE; \
|
0x98f,0x95e,0x92c,0x8fa,0x8c8,0x896,0x864,0x832,
|
||||||
RESTART_CHANNEL_1()
|
0x800,0x7cd,0x79b,0x769,0x737,0x705,0x6d3,0x6a1,
|
||||||
#define UPDATE_CHANNEL_2_FREQ(freq) gpt7cfg1.frequency = freq * DAC_BUFFER_SIZE; \
|
0x670,0x63f,0x60e,0x5dd,0x5ad,0x57d,0x54e,0x51f,
|
||||||
RESTART_CHANNEL_2()
|
0x4f0,0x4c2,0x494,0x467,0x43a,0x40e,0x3e3,0x3b8,
|
||||||
#define GET_CHANNEL_1_FREQ (uint16_t)(gpt6cfg1.frequency * DAC_BUFFER_SIZE)
|
0x38e,0x365,0x33c,0x314,0x2ed,0x2c6,0x2a0,0x27c,
|
||||||
#define GET_CHANNEL_2_FREQ (uint16_t)(gpt7cfg1.frequency * DAC_BUFFER_SIZE)
|
0x258,0x235,0x212,0x1f1,0x1d1,0x1b1,0x193,0x175,
|
||||||
|
0x159,0x13e,0x123,0x10a,0xf2, 0xdb, 0xc5, 0xb0,
|
||||||
|
0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32,
|
||||||
/*
|
0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1,
|
||||||
* GPT6 configuration.
|
0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e,
|
||||||
*/
|
0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89,
|
||||||
// static const GPTConfig gpt6cfg1 = {
|
0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a,0x123,0x13e,
|
||||||
// .frequency = 1000000U,
|
0x159,0x175,0x193,0x1b1,0x1d1,0x1f1,0x212,0x235,
|
||||||
// .callback = NULL,
|
0x258,0x27c,0x2a0,0x2c6,0x2ed,0x314,0x33c,0x365,
|
||||||
// .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */
|
0x38e,0x3b8,0x3e3,0x40e,0x43a,0x467,0x494,0x4c2,
|
||||||
// .dier = 0U
|
0x4f0,0x51f,0x54e,0x57d,0x5ad,0x5dd,0x60e,0x63f,
|
||||||
// };
|
0x670,0x6a1,0x6d3,0x705,0x737,0x769,0x79b,0x7cd
|
||||||
|
|
||||||
GPTConfig gpt6cfg1 = {
|
|
||||||
.frequency = 440U*DAC_BUFFER_SIZE,
|
|
||||||
.callback = NULL,
|
|
||||||
.cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */
|
|
||||||
.dier = 0U
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GPTConfig gpt7cfg1 = {
|
static const dacsample_t dac_buffer_triangle[DAC_BUFFER_SIZE] = {
|
||||||
.frequency = 440U*DAC_BUFFER_SIZE,
|
// 256 values, max 4095
|
||||||
.callback = NULL,
|
0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100,
|
||||||
.cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */
|
0x120,0x140,0x160,0x180,0x1a0,0x1c0,0x1e0,0x200,
|
||||||
.dier = 0U
|
0x220,0x240,0x260,0x280,0x2a0,0x2c0,0x2e0,0x300,
|
||||||
|
0x320,0x340,0x360,0x380,0x3a0,0x3c0,0x3e0,0x400,
|
||||||
|
0x420,0x440,0x460,0x480,0x4a0,0x4c0,0x4e0,0x500,
|
||||||
|
0x520,0x540,0x560,0x580,0x5a0,0x5c0,0x5e0,0x600,
|
||||||
|
0x620,0x640,0x660,0x680,0x6a0,0x6c0,0x6e0,0x700,
|
||||||
|
0x720,0x740,0x760,0x780,0x7a0,0x7c0,0x7e0,0x800,
|
||||||
|
0x81f,0x83f,0x85f,0x87f,0x89f,0x8bf,0x8df,0x8ff,
|
||||||
|
0x91f,0x93f,0x95f,0x97f,0x99f,0x9bf,0x9df,0x9ff,
|
||||||
|
0xa1f,0xa3f,0xa5f,0xa7f,0xa9f,0xabf,0xadf,0xaff,
|
||||||
|
0xb1f,0xb3f,0xb5f,0xb7f,0xb9f,0xbbf,0xbdf,0xbff,
|
||||||
|
0xc1f,0xc3f,0xc5f,0xc7f,0xc9f,0xcbf,0xcdf,0xcff,
|
||||||
|
0xd1f,0xd3f,0xd5f,0xd7f,0xd9f,0xdbf,0xddf,0xdff,
|
||||||
|
0xe1f,0xe3f,0xe5f,0xe7f,0xe9f,0xebf,0xedf,0xeff,
|
||||||
|
0xf1f,0xf3f,0xf5f,0xf7f,0xf9f,0xfbf,0xfdf,0xfff,
|
||||||
|
0xfdf,0xfbf,0xf9f,0xf7f,0xf5f,0xf3f,0xf1f,0xeff,
|
||||||
|
0xedf,0xebf,0xe9f,0xe7f,0xe5f,0xe3f,0xe1f,0xdff,
|
||||||
|
0xddf,0xdbf,0xd9f,0xd7f,0xd5f,0xd3f,0xd1f,0xcff,
|
||||||
|
0xcdf,0xcbf,0xc9f,0xc7f,0xc5f,0xc3f,0xc1f,0xbff,
|
||||||
|
0xbdf,0xbbf,0xb9f,0xb7f,0xb5f,0xb3f,0xb1f,0xaff,
|
||||||
|
0xadf,0xabf,0xa9f,0xa7f,0xa5f,0xa3f,0xa1f,0x9ff,
|
||||||
|
0x9df,0x9bf,0x99f,0x97f,0x95f,0x93f,0x91f,0x8ff,
|
||||||
|
0x8df,0x8bf,0x89f,0x87f,0x85f,0x83f,0x81f,0x800,
|
||||||
|
0x7e0,0x7c0,0x7a0,0x780,0x760,0x740,0x720,0x700,
|
||||||
|
0x6e0,0x6c0,0x6a0,0x680,0x660,0x640,0x620,0x600,
|
||||||
|
0x5e0,0x5c0,0x5a0,0x580,0x560,0x540,0x520,0x500,
|
||||||
|
0x4e0,0x4c0,0x4a0,0x480,0x460,0x440,0x420,0x400,
|
||||||
|
0x3e0,0x3c0,0x3a0,0x380,0x360,0x340,0x320,0x300,
|
||||||
|
0x2e0,0x2c0,0x2a0,0x280,0x260,0x240,0x220,0x200,
|
||||||
|
0x1e0,0x1c0,0x1a0,0x180,0x160,0x140,0x120,0x100,
|
||||||
|
0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20, 0x0
|
||||||
};
|
};
|
||||||
|
|
||||||
GPTConfig gpt8cfg1 = {
|
static const dacsample_t dac_buffer_square[DAC_BUFFER_SIZE] = {
|
||||||
.frequency = 10,
|
|
||||||
.callback = gpt_cb8,
|
|
||||||
.cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */
|
|
||||||
.dier = 0U
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
// };
|
|
||||||
|
|
||||||
// static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = {
|
|
||||||
// 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,
|
|
||||||
// 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
|
|
||||||
// };
|
|
||||||
|
|
||||||
// squarewave
|
|
||||||
static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = {
|
|
||||||
// First half is max, second half is 0
|
// First half is max, second half is 0
|
||||||
[0 ... DAC_BUFFER_SIZE/2-1] = DAC_SAMPLE_MAX,
|
[0 ... DAC_BUFFER_SIZE/2-1] = DAC_SAMPLE_MAX,
|
||||||
[DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE -1] = 0,
|
[DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE -1] = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// squarewave
|
static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = { DAC_OFF_VALUE };
|
||||||
static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = {
|
|
||||||
// opposite of dac_buffer above
|
|
||||||
[0 ... DAC_BUFFER_SIZE/2-1] = 0,
|
|
||||||
[DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE -1] = DAC_SAMPLE_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
|
||||||
* DAC streaming callback.
|
|
||||||
|
/**
|
||||||
|
* Generation of the waveform being passed to the callback. Declared weak so users
|
||||||
|
* can override it with their own waveforms/noises.
|
||||||
*/
|
*/
|
||||||
size_t nx = 0, ny = 0, nz = 0;
|
__attribute__ ((weak))
|
||||||
static void end_cb1(DACDriver *dacp, dacsample_t *buffer, size_t n) {
|
uint16_t dac_value_generate(void) {
|
||||||
|
uint16_t value = DAC_OFF_VALUE;
|
||||||
|
uint8_t working_voices = dac_voices;
|
||||||
|
if (working_voices > DAC_VOICES_MAX)
|
||||||
|
working_voices = DAC_VOICES_MAX;
|
||||||
|
|
||||||
|
if (working_voices > 0) {
|
||||||
|
uint16_t value_avg = 0;
|
||||||
|
for (uint8_t i = 0; i < working_voices; i++) {
|
||||||
|
dac_if[i] = dac_if[i] + ((dac_frequencies[i] * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE);
|
||||||
|
|
||||||
|
// Needed because % doesn't work with floats
|
||||||
|
while (dac_if[i] >= (DAC_BUFFER_SIZE))
|
||||||
|
dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE;
|
||||||
|
|
||||||
|
// Wavetable generation/lookup
|
||||||
|
uint16_t dac_i = (uint16_t)dac_if[i];
|
||||||
|
// SINE
|
||||||
|
value_avg += dac_buffer_sine[dac_i] / working_voices / 3;
|
||||||
|
// TRIANGLE
|
||||||
|
value_avg += dac_buffer_triangle[dac_i] / working_voices / 3;
|
||||||
|
// SQUARE
|
||||||
|
value_avg += dac_buffer_square[dac_i] / working_voices / 3;
|
||||||
|
}
|
||||||
|
value = value_avg;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DAC streaming callback. Does all of the main computing for playing songs.
|
||||||
|
*/
|
||||||
|
static void dac_end(DACDriver * dacp, dacsample_t * sample_p, size_t sample_count) {
|
||||||
|
|
||||||
(void)dacp;
|
(void)dacp;
|
||||||
|
|
||||||
nz++;
|
for (uint8_t s = 0; s < sample_count; s++) {
|
||||||
if (dac_buffer == buffer) {
|
sample_p[s] = dac_value_generate();
|
||||||
nx += n;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ny += n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nz % 1000) == 0) {
|
if (playing_notes) {
|
||||||
// palTogglePad(GPIOD, GPIOD_LED3);
|
note_position += sample_count;
|
||||||
|
|
||||||
|
// End of the note - 35 is arbitary here, but gets us close to AVR's timing
|
||||||
|
if ((note_position >= (note_length*DAC_SAMPLE_RATE/35))) {
|
||||||
|
stop_note((*notes_pointer)[current_note][0]);
|
||||||
|
current_note++;
|
||||||
|
if (current_note >= notes_count) {
|
||||||
|
if (notes_repeat) {
|
||||||
|
current_note = 0;
|
||||||
|
} else {
|
||||||
|
playing_notes = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
play_note((*notes_pointer)[current_note][0], 15);
|
||||||
|
envelope_index = 0;
|
||||||
|
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
|
||||||
|
|
||||||
|
// Skip forward in the next note's length if we've over shot the last, so
|
||||||
|
// the overall length of the song is the same
|
||||||
|
note_position = note_position - (note_length*DAC_SAMPLE_RATE/35);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void dac_error(DACDriver *dacp, dacerror_t err) {
|
||||||
* DAC error callback.
|
|
||||||
*/
|
|
||||||
static void error_cb1(DACDriver *dacp, dacerror_t err) {
|
|
||||||
|
|
||||||
(void)dacp;
|
(void)dacp;
|
||||||
(void)err;
|
(void)err;
|
||||||
|
|
||||||
chSysHalt("DAC failure");
|
chSysHalt("DAC failure. halp");
|
||||||
}
|
}
|
||||||
|
|
||||||
static const DACConfig dac1cfg1 = {
|
static const GPTConfig gpt6cfg1 = {
|
||||||
|
.frequency = DAC_SAMPLE_RATE * 3,
|
||||||
|
.callback = NULL,
|
||||||
|
.cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */
|
||||||
|
.dier = 0U
|
||||||
|
};
|
||||||
|
|
||||||
|
static const DACConfig dac_conf = {
|
||||||
.init = DAC_SAMPLE_MAX,
|
.init = DAC_SAMPLE_MAX,
|
||||||
.datamode = DAC_DHRM_12BIT_RIGHT
|
.datamode = DAC_DHRM_12BIT_RIGHT
|
||||||
};
|
};
|
||||||
|
|
||||||
static const DACConversionGroup dacgrpcfg1 = {
|
/**
|
||||||
|
* @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered
|
||||||
|
* on the rising edge after 3 APB1 clock cycles, causing our gpt6cfg1.frequency
|
||||||
|
* to be a third of what we expect.
|
||||||
|
*
|
||||||
|
* Here are all the values for DAC_TRG (TSEL in the ref manual)
|
||||||
|
* TIM15_TRGO 0b011
|
||||||
|
* TIM2_TRGO 0b100
|
||||||
|
* TIM3_TRGO 0b001
|
||||||
|
* TIM6_TRGO 0b000
|
||||||
|
* TIM7_TRGO 0b010
|
||||||
|
* EXTI9 0b110
|
||||||
|
* SWTRIG 0b111
|
||||||
|
*/
|
||||||
|
static const DACConversionGroup dac_conv_cfg = {
|
||||||
.num_channels = 1U,
|
.num_channels = 1U,
|
||||||
.end_cb = end_cb1,
|
.end_cb = dac_end,
|
||||||
.error_cb = error_cb1,
|
.error_cb = dac_error,
|
||||||
.trigger = DAC_TRG(0)
|
.trigger = DAC_TRG(0b000)
|
||||||
};
|
|
||||||
|
|
||||||
static const DACConfig dac1cfg2 = {
|
|
||||||
.init = DAC_SAMPLE_MAX,
|
|
||||||
.datamode = DAC_DHRM_12BIT_RIGHT
|
|
||||||
};
|
|
||||||
|
|
||||||
static const DACConversionGroup dacgrpcfg2 = {
|
|
||||||
.num_channels = 1U,
|
|
||||||
.end_cb = end_cb1,
|
|
||||||
.error_cb = error_cb1,
|
|
||||||
.trigger = DAC_TRG(0)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void audio_init() {
|
void audio_init() {
|
||||||
|
@ -292,26 +275,20 @@ void audio_init() {
|
||||||
#endif
|
#endif
|
||||||
#endif // ARM EEPROM
|
#endif // ARM EEPROM
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
dacStart(&DACD2, &dac1cfg2);
|
|
||||||
|
|
||||||
/*
|
#if defined(A4_AUDIO)
|
||||||
* Starting GPT6/7 driver, it is used for triggering the DAC.
|
palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG );
|
||||||
*/
|
dacStart(&DACD1, &dac_conf);
|
||||||
START_CHANNEL_1();
|
dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE);
|
||||||
START_CHANNEL_2();
|
#endif
|
||||||
|
#if defined(A5_AUDIO)
|
||||||
|
palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG );
|
||||||
|
dacStart(&DACD2, &dac_conf);
|
||||||
|
dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
gptStart(&GPTD6, &gpt6cfg1);
|
||||||
* Starting a continuous conversion.
|
gptStartContinuous(&GPTD6, 2U);
|
||||||
*/
|
|
||||||
dacStartConversion(&DACD1, &dacgrpcfg1, (dacsample_t *)dac_buffer, DAC_BUFFER_SIZE);
|
|
||||||
dacStartConversion(&DACD2, &dacgrpcfg2, (dacsample_t *)dac_buffer_2, DAC_BUFFER_SIZE);
|
|
||||||
|
|
||||||
audio_initialized = true;
|
audio_initialized = true;
|
||||||
|
|
||||||
|
@ -329,22 +306,13 @@ void stop_all_notes() {
|
||||||
if (!audio_initialized) {
|
if (!audio_initialized) {
|
||||||
audio_init();
|
audio_init();
|
||||||
}
|
}
|
||||||
voices = 0;
|
dac_voices = 0;
|
||||||
|
|
||||||
gptStopTimer(&GPTD6);
|
|
||||||
gptStopTimer(&GPTD7);
|
|
||||||
gptStopTimer(&GPTD8);
|
|
||||||
|
|
||||||
playing_notes = false;
|
playing_notes = false;
|
||||||
playing_note = false;
|
playing_note = false;
|
||||||
frequency = 0;
|
|
||||||
frequency_alt = 0;
|
|
||||||
volume = 0;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 8; i++)
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
{
|
dac_frequencies[i] = 0;
|
||||||
frequencies[i] = 0;
|
|
||||||
volumes[i] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,32 +324,20 @@ void stop_note(float freq) {
|
||||||
audio_init();
|
audio_init();
|
||||||
}
|
}
|
||||||
for (int i = 7; i >= 0; i--) {
|
for (int i = 7; i >= 0; i--) {
|
||||||
if (frequencies[i] == freq) {
|
if (dac_frequencies[i] == freq) {
|
||||||
frequencies[i] = 0;
|
dac_frequencies[i] = 0;
|
||||||
volumes[i] = 0;
|
|
||||||
for (int j = i; (j < 7); j++) {
|
for (int j = i; (j < 7); j++) {
|
||||||
frequencies[j] = frequencies[j+1];
|
dac_frequencies[j] = dac_frequencies[j+1];
|
||||||
frequencies[j+1] = 0;
|
dac_frequencies[j+1] = 0;
|
||||||
volumes[j] = volumes[j+1];
|
|
||||||
volumes[j+1] = 0;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
voices--;
|
dac_voices--;
|
||||||
if (voices < 0) {
|
if (dac_voices < 0) {
|
||||||
voices = 0;
|
dac_voices = 0;
|
||||||
}
|
}
|
||||||
if (voice_place >= voices) {
|
if (dac_voices == 0) {
|
||||||
voice_place = 0;
|
|
||||||
}
|
|
||||||
if (voices == 0) {
|
|
||||||
STOP_CHANNEL_1();
|
|
||||||
STOP_CHANNEL_2();
|
|
||||||
gptStopTimer(&GPTD8);
|
|
||||||
frequency = 0;
|
|
||||||
frequency_alt = 0;
|
|
||||||
volume = 0;
|
|
||||||
playing_note = false;
|
playing_note = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -406,196 +362,6 @@ float vibrato(float average_freq) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void gpt_cb8(GPTDriver *gptp) {
|
|
||||||
float freq;
|
|
||||||
|
|
||||||
if (playing_note) {
|
|
||||||
if (voices > 0) {
|
|
||||||
|
|
||||||
float freq_alt = 0;
|
|
||||||
if (voices > 1) {
|
|
||||||
if (polyphony_rate == 0) {
|
|
||||||
if (glissando) {
|
|
||||||
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)) {
|
|
||||||
frequency_alt = frequency_alt * pow(2, -440/frequency_alt/12/2);
|
|
||||||
} else {
|
|
||||||
frequency_alt = frequencies[voices - 2];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
frequency_alt = frequencies[voices - 2];
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VIBRATO_ENABLE
|
|
||||||
if (vibrato_strength > 0) {
|
|
||||||
freq_alt = vibrato(frequency_alt);
|
|
||||||
} else {
|
|
||||||
freq_alt = frequency_alt;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
freq_alt = frequency_alt;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (envelope_index < 65535) {
|
|
||||||
envelope_index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
freq_alt = voice_envelope(freq_alt);
|
|
||||||
|
|
||||||
if (freq_alt < 30.517578125) {
|
|
||||||
freq_alt = 30.52;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GET_CHANNEL_2_FREQ != (uint16_t)freq_alt) {
|
|
||||||
UPDATE_CHANNEL_2_FREQ(freq_alt);
|
|
||||||
} else {
|
|
||||||
RESTART_CHANNEL_2();
|
|
||||||
}
|
|
||||||
//note_timbre;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (polyphony_rate > 0) {
|
|
||||||
if (voices > 1) {
|
|
||||||
voice_place %= voices;
|
|
||||||
if (place++ > (frequencies[voice_place] / polyphony_rate)) {
|
|
||||||
voice_place = (voice_place + 1) % voices;
|
|
||||||
place = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VIBRATO_ENABLE
|
|
||||||
if (vibrato_strength > 0) {
|
|
||||||
freq = vibrato(frequencies[voice_place]);
|
|
||||||
} else {
|
|
||||||
freq = frequencies[voice_place];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
freq = frequencies[voice_place];
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
if (glissando) {
|
|
||||||
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)) {
|
|
||||||
frequency = frequency * pow(2, -440/frequency/12/2);
|
|
||||||
} else {
|
|
||||||
frequency = frequencies[voices - 1];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
frequency = frequencies[voices - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VIBRATO_ENABLE
|
|
||||||
if (vibrato_strength > 0) {
|
|
||||||
freq = vibrato(frequency);
|
|
||||||
} else {
|
|
||||||
freq = frequency;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
freq = frequency;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (envelope_index < 65535) {
|
|
||||||
envelope_index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
freq = voice_envelope(freq);
|
|
||||||
|
|
||||||
if (freq < 30.517578125) {
|
|
||||||
freq = 30.52;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (GET_CHANNEL_1_FREQ != (uint16_t)freq) {
|
|
||||||
UPDATE_CHANNEL_1_FREQ(freq);
|
|
||||||
} else {
|
|
||||||
RESTART_CHANNEL_1();
|
|
||||||
}
|
|
||||||
//note_timbre;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playing_notes) {
|
|
||||||
if (note_frequency > 0) {
|
|
||||||
#ifdef VIBRATO_ENABLE
|
|
||||||
if (vibrato_strength > 0) {
|
|
||||||
freq = vibrato(note_frequency);
|
|
||||||
} else {
|
|
||||||
freq = note_frequency;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
freq = note_frequency;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (envelope_index < 65535) {
|
|
||||||
envelope_index++;
|
|
||||||
}
|
|
||||||
freq = voice_envelope(freq);
|
|
||||||
|
|
||||||
|
|
||||||
if (GET_CHANNEL_1_FREQ != (uint16_t)freq) {
|
|
||||||
UPDATE_CHANNEL_1_FREQ(freq);
|
|
||||||
UPDATE_CHANNEL_2_FREQ(freq);
|
|
||||||
}
|
|
||||||
//note_timbre;
|
|
||||||
} else {
|
|
||||||
// gptStopTimer(&GPTD6);
|
|
||||||
// gptStopTimer(&GPTD7);
|
|
||||||
}
|
|
||||||
|
|
||||||
note_position++;
|
|
||||||
bool end_of_note = false;
|
|
||||||
if (GET_CHANNEL_1_FREQ > 0) {
|
|
||||||
if (!note_resting)
|
|
||||||
end_of_note = (note_position >= (note_length*8 - 1));
|
|
||||||
else
|
|
||||||
end_of_note = (note_position >= (note_length*8));
|
|
||||||
} else {
|
|
||||||
end_of_note = (note_position >= (note_length*8));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_of_note) {
|
|
||||||
current_note++;
|
|
||||||
if (current_note >= notes_count) {
|
|
||||||
if (notes_repeat) {
|
|
||||||
current_note = 0;
|
|
||||||
} else {
|
|
||||||
STOP_CHANNEL_1();
|
|
||||||
STOP_CHANNEL_2();
|
|
||||||
// gptStopTimer(&GPTD8);
|
|
||||||
playing_notes = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!note_resting) {
|
|
||||||
note_resting = true;
|
|
||||||
current_note--;
|
|
||||||
if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
|
|
||||||
note_frequency = 0;
|
|
||||||
note_length = 1;
|
|
||||||
} else {
|
|
||||||
note_frequency = (*notes_pointer)[current_note][0];
|
|
||||||
note_length = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
note_resting = false;
|
|
||||||
envelope_index = 0;
|
|
||||||
note_frequency = (*notes_pointer)[current_note][0];
|
|
||||||
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
note_position = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!audio_config.enable) {
|
|
||||||
playing_notes = false;
|
|
||||||
playing_note = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void play_note(float freq, int vol) {
|
void play_note(float freq, int vol) {
|
||||||
|
|
||||||
|
@ -605,29 +371,19 @@ void play_note(float freq, int vol) {
|
||||||
audio_init();
|
audio_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_config.enable && voices < 8) {
|
if (audio_config.enable && dac_voices < 8) {
|
||||||
|
|
||||||
// Cancel notes if notes are playing
|
|
||||||
if (playing_notes) {
|
|
||||||
stop_all_notes();
|
|
||||||
}
|
|
||||||
|
|
||||||
playing_note = true;
|
playing_note = true;
|
||||||
|
|
||||||
envelope_index = 0;
|
|
||||||
|
|
||||||
if (freq > 0) {
|
if (freq > 0) {
|
||||||
frequencies[voices] = freq;
|
envelope_index = 0;
|
||||||
volumes[voices] = vol;
|
dac_frequencies[dac_voices] = freq;
|
||||||
voices++;
|
dac_voices++;
|
||||||
}
|
}
|
||||||
|
|
||||||
gptStart(&GPTD8, &gpt8cfg1);
|
|
||||||
gptStartContinuous(&GPTD8, 2U);
|
|
||||||
RESTART_CHANNEL_1();
|
|
||||||
RESTART_CHANNEL_2();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((weak))
|
||||||
|
void dac_setup_note(void) {
|
||||||
|
dac_if[dac_voices] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) {
|
void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) {
|
||||||
|
@ -638,31 +394,26 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) {
|
||||||
|
|
||||||
if (audio_config.enable) {
|
if (audio_config.enable) {
|
||||||
|
|
||||||
// Cancel note if a note is playing
|
|
||||||
if (playing_note) {
|
|
||||||
stop_all_notes();
|
|
||||||
}
|
|
||||||
|
|
||||||
playing_notes = true;
|
playing_notes = true;
|
||||||
|
|
||||||
notes_pointer = np;
|
notes_pointer = np;
|
||||||
notes_count = n_count;
|
notes_count = n_count;
|
||||||
notes_repeat = n_repeat;
|
notes_repeat = n_repeat;
|
||||||
|
|
||||||
place = 0;
|
|
||||||
current_note = 0;
|
current_note = 0;
|
||||||
|
|
||||||
note_frequency = (*notes_pointer)[current_note][0];
|
|
||||||
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
|
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
|
||||||
note_position = 0;
|
note_position = 0;
|
||||||
|
|
||||||
gptStart(&GPTD8, &gpt8cfg1);
|
play_note((*notes_pointer)[current_note][0], 15);
|
||||||
gptStartContinuous(&GPTD8, 2U);
|
|
||||||
RESTART_CHANNEL_1();
|
|
||||||
RESTART_CHANNEL_2();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_playing_note(void) {
|
||||||
|
return playing_note;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_playing_notes(void) {
|
bool is_playing_notes(void) {
|
||||||
return playing_notes;
|
return playing_notes;
|
||||||
}
|
}
|
||||||
|
@ -770,3 +521,11 @@ void increase_tempo(uint8_t tempo_change) {
|
||||||
note_tempo -= tempo_change;
|
note_tempo -= tempo_change;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t dac_number_of_voices(void) {
|
||||||
|
return dac_voices;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dac_get_frequency(uint8_t index) {
|
||||||
|
return dac_frequencies[index];
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/* Copyright 2019 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of the dac_buffer arrays. All must be the same size.
|
||||||
|
*/
|
||||||
|
#define DAC_BUFFER_SIZE 256U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highest value allowed by our 12bit DAC.
|
||||||
|
*/
|
||||||
|
#ifndef DAC_SAMPLE_MAX
|
||||||
|
#define DAC_SAMPLE_MAX 4095U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// #define DAC_LOW_QUALITY
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These presets allow you to quickly switch between quality/voice settings for
|
||||||
|
* the DAC. The sample rate and number of voices roughly has an inverse
|
||||||
|
* relationship - slightly higher sample rates may be possible.
|
||||||
|
*/
|
||||||
|
#ifdef DAC_VERY_LOW_QUALITY
|
||||||
|
#define DAC_SAMPLE_RATE 11025U
|
||||||
|
#define DAC_VOICES_MAX 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DAC_LOW_QUALITY
|
||||||
|
#define DAC_SAMPLE_RATE 22050U
|
||||||
|
#define DAC_VOICES_MAX 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DAC_HIGH_QUALITY
|
||||||
|
#define DAC_SAMPLE_RATE 44100U
|
||||||
|
#define DAC_VOICES_MAX 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DAC_VERY_HIGH_QUALITY
|
||||||
|
#define DAC_SAMPLE_RATE 88200U
|
||||||
|
#define DAC_VOICES_MAX 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Effective bitrate of the DAC. 44.1khz is the standard for most audio - any
|
||||||
|
* lower will sacrifice perceptible audio quality. Any higher will limit the
|
||||||
|
* number of simultaneous voices. In most situations, a tenth (1/10) of the
|
||||||
|
* sample rate is where notes become unbearable.
|
||||||
|
*/
|
||||||
|
#ifndef DAC_SAMPLE_RATE
|
||||||
|
#define DAC_SAMPLE_RATE 44100U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of voices (in polyphony) that are supported. If too high a value
|
||||||
|
* is used here, the keyboard will freeze and glitch-out when that many voices
|
||||||
|
* are being played.
|
||||||
|
*/
|
||||||
|
#ifndef DAC_VOICES_MAX
|
||||||
|
#define DAC_VOICES_MAX 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default value of the DAC when not playing anything. Certain hardware
|
||||||
|
* setups may require a high (DAC_SAMPLE_MAX) or low (0) value here.
|
||||||
|
*/
|
||||||
|
#ifndef DAC_OFF_VALUE
|
||||||
|
#define DAC_OFF_VALUE DAC_SAMPLE_MAX / 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t dac_number_of_voices(void);
|
||||||
|
float dac_get_frequency(uint8_t index);
|
||||||
|
uint16_t dac_value_generate(void);
|
||||||
|
void dac_setup_note(void);
|
|
@ -195,6 +195,16 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
|
||||||
music_sequence_interval+=10;
|
music_sequence_interval+=10;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keycode == KC_LEFT) {
|
||||||
|
music_offset--;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keycode == KC_RIGHT) {
|
||||||
|
music_offset++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t note = 36;
|
uint8_t note = 36;
|
||||||
|
|
|
@ -141,8 +141,8 @@
|
||||||
#define STM32_GPT_USE_TIM3 FALSE
|
#define STM32_GPT_USE_TIM3 FALSE
|
||||||
#define STM32_GPT_USE_TIM4 FALSE
|
#define STM32_GPT_USE_TIM4 FALSE
|
||||||
#define STM32_GPT_USE_TIM6 TRUE
|
#define STM32_GPT_USE_TIM6 TRUE
|
||||||
#define STM32_GPT_USE_TIM7 TRUE
|
#define STM32_GPT_USE_TIM7 FALSE
|
||||||
#define STM32_GPT_USE_TIM8 TRUE
|
#define STM32_GPT_USE_TIM8 FALSE
|
||||||
#define STM32_GPT_TIM1_IRQ_PRIORITY 7
|
#define STM32_GPT_TIM1_IRQ_PRIORITY 7
|
||||||
#define STM32_GPT_TIM2_IRQ_PRIORITY 7
|
#define STM32_GPT_TIM2_IRQ_PRIORITY 7
|
||||||
#define STM32_GPT_TIM3_IRQ_PRIORITY 7
|
#define STM32_GPT_TIM3_IRQ_PRIORITY 7
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#! /bin/python
|
||||||
|
#
|
||||||
|
# Copyright 2019 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 <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
import wave, struct, sys
|
||||||
|
|
||||||
|
waveFile = wave.open(sys.argv[1], 'r')
|
||||||
|
# print(str(waveFile.getparams()))
|
||||||
|
# sys.exit()
|
||||||
|
|
||||||
|
if (waveFile.getsampwidth() != 2):
|
||||||
|
raise(Exception("This script currently only works with 16bit audio files"))
|
||||||
|
|
||||||
|
length = waveFile.getnframes()
|
||||||
|
out = "#define DAC_SAMPLE_CUSTOM_LENGTH " + str(length) + "\n\n"
|
||||||
|
out += "static const dacsample_t dac_sample_custom[" + str(length) + "] = {"
|
||||||
|
for i in range(0,length):
|
||||||
|
if (i % 8 == 0):
|
||||||
|
out += "\n "
|
||||||
|
waveData = waveFile.readframes(1)
|
||||||
|
data = struct.unpack("<h", waveData)
|
||||||
|
out += str(int((int(data[0]) + 0x8000) / 16)) + ", "
|
||||||
|
out = out[:-2]
|
||||||
|
out += "\n};"
|
||||||
|
print(out)
|
|
@ -0,0 +1,40 @@
|
||||||
|
#! /bin/python
|
||||||
|
#
|
||||||
|
# Copyright 2019 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 <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
import wave, struct, sys
|
||||||
|
|
||||||
|
waveFile = wave.open(sys.argv[1], 'r')
|
||||||
|
|
||||||
|
length = waveFile.getnframes()
|
||||||
|
out = "#define DAC_WAVETABLE_CUSTOM_LENGTH " + str(int(length / 256)) + "\n\n"
|
||||||
|
out += "static const dacsample_t dac_wavetable_custom[" + str(int(length / 256)) + "][256] = {"
|
||||||
|
for i in range(0,length):
|
||||||
|
if (i % 8 == 0):
|
||||||
|
out += "\n "
|
||||||
|
if (i % 256 == 0):
|
||||||
|
out = out[:-2]
|
||||||
|
out += "{\n "
|
||||||
|
waveData = waveFile.readframes(1)
|
||||||
|
data = struct.unpack("<h", waveData)
|
||||||
|
out += str(int((int(data[0]) + 0x8000) / 16)) + ", "
|
||||||
|
if (i % 256 == 255):
|
||||||
|
out = out[:-2]
|
||||||
|
out += "\n },"
|
||||||
|
out = out[:-1]
|
||||||
|
out += "\n};"
|
||||||
|
print(out)
|
Loading…
Reference in New Issue