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 C6_AUDIO
|
||||
|
||||
#define A5_AUDIO
|
||||
#define DAC_OFF_VALUE 4095
|
||||
|
||||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
||||
#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 C6_AUDIO
|
||||
|
||||
#define A5_AUDIO
|
||||
|
||||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
||||
#define DEBOUNCE 6
|
||||
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
#include "rev6.h"
|
||||
|
||||
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) {
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef AUDIO_H
|
||||
#define AUDIO_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -27,6 +27,9 @@
|
|||
#include "voices.h"
|
||||
#include "quantum.h"
|
||||
#include <math.h>
|
||||
#if defined(PROTOCOL_CHIBIOS)
|
||||
#include "audio_arm.h"
|
||||
#endif
|
||||
|
||||
// Largely untested PWM audio mode (doesn't sound as good)
|
||||
// #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_LOOP(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), true)
|
||||
|
||||
bool is_playing_note(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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -26,21 +26,8 @@
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int voices = 0;
|
||||
int voice_place = 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;
|
||||
uint8_t dac_voices = 0;
|
||||
float dac_frequencies[8] = { 0.0 };
|
||||
|
||||
bool playing_notes = false;
|
||||
bool playing_note = false;
|
||||
|
@ -48,14 +35,12 @@ float note_frequency = 0;
|
|||
float note_length = 0;
|
||||
uint8_t note_tempo = TEMPO_DEFAULT;
|
||||
float note_timbre = TIMBRE_DEFAULT;
|
||||
uint16_t note_position = 0;
|
||||
uint32_t note_position = 0;
|
||||
float (* notes_pointer)[][2];
|
||||
uint16_t notes_count;
|
||||
bool notes_repeat;
|
||||
bool note_resting = false;
|
||||
|
||||
uint16_t current_note = 0;
|
||||
uint8_t rest_counter = 0;
|
||||
|
||||
#ifdef VIBRATO_ENABLE
|
||||
float vibrato_counter = 0;
|
||||
|
@ -77,200 +62,198 @@ bool glissando = true;
|
|||
#endif
|
||||
float startup_song[][2] = STARTUP_SONG;
|
||||
|
||||
static void gpt_cb8(GPTDriver *gptp);
|
||||
|
||||
#define DAC_BUFFER_SIZE 100
|
||||
#ifndef DAC_SAMPLE_MAX
|
||||
#define DAC_SAMPLE_MAX 65535U
|
||||
#endif
|
||||
|
||||
#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_2(); \
|
||||
START_CHANNEL_2()
|
||||
#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 (uint16_t)(gpt6cfg1.frequency * DAC_BUFFER_SIZE)
|
||||
#define GET_CHANNEL_2_FREQ (uint16_t)(gpt7cfg1.frequency * DAC_BUFFER_SIZE)
|
||||
|
||||
|
||||
/*
|
||||
* 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 = 440U*DAC_BUFFER_SIZE,
|
||||
.callback = NULL,
|
||||
.cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */
|
||||
.dier = 0U
|
||||
static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = {
|
||||
// 256 values, max 4095
|
||||
0x800,0x832,0x864,0x896,0x8c8,0x8fa,0x92c,0x95e,
|
||||
0x98f,0x9c0,0x9f1,0xa22,0xa52,0xa82,0xab1,0xae0,
|
||||
0xb0f,0xb3d,0xb6b,0xb98,0xbc5,0xbf1,0xc1c,0xc47,
|
||||
0xc71,0xc9a,0xcc3,0xceb,0xd12,0xd39,0xd5f,0xd83,
|
||||
0xda7,0xdca,0xded,0xe0e,0xe2e,0xe4e,0xe6c,0xe8a,
|
||||
0xea6,0xec1,0xedc,0xef5,0xf0d,0xf24,0xf3a,0xf4f,
|
||||
0xf63,0xf76,0xf87,0xf98,0xfa7,0xfb5,0xfc2,0xfcd,
|
||||
0xfd8,0xfe1,0xfe9,0xff0,0xff5,0xff9,0xffd,0xffe,
|
||||
0xfff,0xffe,0xffd,0xff9,0xff5,0xff0,0xfe9,0xfe1,
|
||||
0xfd8,0xfcd,0xfc2,0xfb5,0xfa7,0xf98,0xf87,0xf76,
|
||||
0xf63,0xf4f,0xf3a,0xf24,0xf0d,0xef5,0xedc,0xec1,
|
||||
0xea6,0xe8a,0xe6c,0xe4e,0xe2e,0xe0e,0xded,0xdca,
|
||||
0xda7,0xd83,0xd5f,0xd39,0xd12,0xceb,0xcc3,0xc9a,
|
||||
0xc71,0xc47,0xc1c,0xbf1,0xbc5,0xb98,0xb6b,0xb3d,
|
||||
0xb0f,0xae0,0xab1,0xa82,0xa52,0xa22,0x9f1,0x9c0,
|
||||
0x98f,0x95e,0x92c,0x8fa,0x8c8,0x896,0x864,0x832,
|
||||
0x800,0x7cd,0x79b,0x769,0x737,0x705,0x6d3,0x6a1,
|
||||
0x670,0x63f,0x60e,0x5dd,0x5ad,0x57d,0x54e,0x51f,
|
||||
0x4f0,0x4c2,0x494,0x467,0x43a,0x40e,0x3e3,0x3b8,
|
||||
0x38e,0x365,0x33c,0x314,0x2ed,0x2c6,0x2a0,0x27c,
|
||||
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,
|
||||
0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e,
|
||||
0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89,
|
||||
0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a,0x123,0x13e,
|
||||
0x159,0x175,0x193,0x1b1,0x1d1,0x1f1,0x212,0x235,
|
||||
0x258,0x27c,0x2a0,0x2c6,0x2ed,0x314,0x33c,0x365,
|
||||
0x38e,0x3b8,0x3e3,0x40e,0x43a,0x467,0x494,0x4c2,
|
||||
0x4f0,0x51f,0x54e,0x57d,0x5ad,0x5dd,0x60e,0x63f,
|
||||
0x670,0x6a1,0x6d3,0x705,0x737,0x769,0x79b,0x7cd
|
||||
};
|
||||
|
||||
GPTConfig gpt7cfg1 = {
|
||||
.frequency = 440U*DAC_BUFFER_SIZE,
|
||||
.callback = NULL,
|
||||
.cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */
|
||||
.dier = 0U
|
||||
static const dacsample_t dac_buffer_triangle[DAC_BUFFER_SIZE] = {
|
||||
// 256 values, max 4095
|
||||
0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100,
|
||||
0x120,0x140,0x160,0x180,0x1a0,0x1c0,0x1e0,0x200,
|
||||
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 = {
|
||||
.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] = {
|
||||
static const dacsample_t dac_buffer_square[DAC_BUFFER_SIZE] = {
|
||||
// First half is max, second half is 0
|
||||
[0 ... DAC_BUFFER_SIZE/2-1] = DAC_SAMPLE_MAX,
|
||||
[DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE -1] = 0,
|
||||
};
|
||||
|
||||
// squarewave
|
||||
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 dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = { DAC_OFF_VALUE };
|
||||
|
||||
/*
|
||||
* DAC streaming callback.
|
||||
static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
static void end_cb1(DACDriver *dacp, dacsample_t *buffer, size_t n) {
|
||||
__attribute__ ((weak))
|
||||
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;
|
||||
|
||||
nz++;
|
||||
if (dac_buffer == buffer) {
|
||||
nx += n;
|
||||
}
|
||||
else {
|
||||
ny += n;
|
||||
for (uint8_t s = 0; s < sample_count; s++) {
|
||||
sample_p[s] = dac_value_generate();
|
||||
}
|
||||
|
||||
if ((nz % 1000) == 0) {
|
||||
// palTogglePad(GPIOD, GPIOD_LED3);
|
||||
if (playing_notes) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DAC error callback.
|
||||
*/
|
||||
static void error_cb1(DACDriver *dacp, dacerror_t err) {
|
||||
static void dac_error(DACDriver *dacp, dacerror_t err) {
|
||||
|
||||
(void)dacp;
|
||||
(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,
|
||||
.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,
|
||||
.end_cb = end_cb1,
|
||||
.error_cb = error_cb1,
|
||||
.trigger = DAC_TRG(0)
|
||||
};
|
||||
|
||||
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)
|
||||
.end_cb = dac_end,
|
||||
.error_cb = dac_error,
|
||||
.trigger = DAC_TRG(0b000)
|
||||
};
|
||||
|
||||
void audio_init() {
|
||||
|
@ -292,26 +275,20 @@ void audio_init() {
|
|||
#endif
|
||||
#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);
|
||||
|
||||
/*
|
||||
* Starting GPT6/7 driver, it is used for triggering the DAC.
|
||||
*/
|
||||
START_CHANNEL_1();
|
||||
START_CHANNEL_2();
|
||||
#if defined(A4_AUDIO)
|
||||
palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG );
|
||||
dacStart(&DACD1, &dac_conf);
|
||||
dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE);
|
||||
#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
|
||||
|
||||
/*
|
||||
* Starting a continuous conversion.
|
||||
*/
|
||||
dacStartConversion(&DACD1, &dacgrpcfg1, (dacsample_t *)dac_buffer, DAC_BUFFER_SIZE);
|
||||
dacStartConversion(&DACD2, &dacgrpcfg2, (dacsample_t *)dac_buffer_2, DAC_BUFFER_SIZE);
|
||||
gptStart(&GPTD6, &gpt6cfg1);
|
||||
gptStartContinuous(&GPTD6, 2U);
|
||||
|
||||
audio_initialized = true;
|
||||
|
||||
|
@ -329,22 +306,13 @@ void stop_all_notes() {
|
|||
if (!audio_initialized) {
|
||||
audio_init();
|
||||
}
|
||||
voices = 0;
|
||||
|
||||
gptStopTimer(&GPTD6);
|
||||
gptStopTimer(&GPTD7);
|
||||
gptStopTimer(&GPTD8);
|
||||
dac_voices = 0;
|
||||
|
||||
playing_notes = false;
|
||||
playing_note = false;
|
||||
frequency = 0;
|
||||
frequency_alt = 0;
|
||||
volume = 0;
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
frequencies[i] = 0;
|
||||
volumes[i] = 0;
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
dac_frequencies[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,32 +324,20 @@ void stop_note(float freq) {
|
|||
audio_init();
|
||||
}
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
if (frequencies[i] == freq) {
|
||||
frequencies[i] = 0;
|
||||
volumes[i] = 0;
|
||||
if (dac_frequencies[i] == freq) {
|
||||
dac_frequencies[i] = 0;
|
||||
for (int j = i; (j < 7); j++) {
|
||||
frequencies[j] = frequencies[j+1];
|
||||
frequencies[j+1] = 0;
|
||||
volumes[j] = volumes[j+1];
|
||||
volumes[j+1] = 0;
|
||||
dac_frequencies[j] = dac_frequencies[j+1];
|
||||
dac_frequencies[j+1] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
voices--;
|
||||
if (voices < 0) {
|
||||
voices = 0;
|
||||
dac_voices--;
|
||||
if (dac_voices < 0) {
|
||||
dac_voices = 0;
|
||||
}
|
||||
if (voice_place >= voices) {
|
||||
voice_place = 0;
|
||||
}
|
||||
if (voices == 0) {
|
||||
STOP_CHANNEL_1();
|
||||
STOP_CHANNEL_2();
|
||||
gptStopTimer(&GPTD8);
|
||||
frequency = 0;
|
||||
frequency_alt = 0;
|
||||
volume = 0;
|
||||
if (dac_voices == 0) {
|
||||
playing_note = false;
|
||||
}
|
||||
}
|
||||
|
@ -406,196 +362,6 @@ float vibrato(float average_freq) {
|
|||
|
||||
#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) {
|
||||
|
||||
|
@ -605,29 +371,19 @@ void play_note(float freq, int vol) {
|
|||
audio_init();
|
||||
}
|
||||
|
||||
if (audio_config.enable && voices < 8) {
|
||||
|
||||
// Cancel notes if notes are playing
|
||||
if (playing_notes) {
|
||||
stop_all_notes();
|
||||
}
|
||||
|
||||
if (audio_config.enable && dac_voices < 8) {
|
||||
playing_note = true;
|
||||
|
||||
envelope_index = 0;
|
||||
|
||||
if (freq > 0) {
|
||||
frequencies[voices] = freq;
|
||||
volumes[voices] = vol;
|
||||
voices++;
|
||||
envelope_index = 0;
|
||||
dac_frequencies[dac_voices] = freq;
|
||||
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) {
|
||||
|
@ -638,31 +394,26 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) {
|
|||
|
||||
if (audio_config.enable) {
|
||||
|
||||
// Cancel note if a note is playing
|
||||
if (playing_note) {
|
||||
stop_all_notes();
|
||||
}
|
||||
|
||||
playing_notes = true;
|
||||
|
||||
notes_pointer = np;
|
||||
notes_count = n_count;
|
||||
notes_repeat = n_repeat;
|
||||
|
||||
place = 0;
|
||||
current_note = 0;
|
||||
|
||||
note_frequency = (*notes_pointer)[current_note][0];
|
||||
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
|
||||
note_position = 0;
|
||||
|
||||
gptStart(&GPTD8, &gpt8cfg1);
|
||||
gptStartContinuous(&GPTD8, 2U);
|
||||
RESTART_CHANNEL_1();
|
||||
RESTART_CHANNEL_2();
|
||||
play_note((*notes_pointer)[current_note][0], 15);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool is_playing_note(void) {
|
||||
return playing_note;
|
||||
}
|
||||
|
||||
bool is_playing_notes(void) {
|
||||
return playing_notes;
|
||||
}
|
||||
|
@ -770,3 +521,11 @@ void increase_tempo(uint8_t 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;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == KC_LEFT) {
|
||||
music_offset--;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == KC_RIGHT) {
|
||||
music_offset++;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t note = 36;
|
||||
|
|
|
@ -141,8 +141,8 @@
|
|||
#define STM32_GPT_USE_TIM3 FALSE
|
||||
#define STM32_GPT_USE_TIM4 FALSE
|
||||
#define STM32_GPT_USE_TIM6 TRUE
|
||||
#define STM32_GPT_USE_TIM7 TRUE
|
||||
#define STM32_GPT_USE_TIM8 TRUE
|
||||
#define STM32_GPT_USE_TIM7 FALSE
|
||||
#define STM32_GPT_USE_TIM8 FALSE
|
||||
#define STM32_GPT_TIM1_IRQ_PRIORITY 7
|
||||
#define STM32_GPT_TIM2_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