add sample and wavetable examples, parsers for both

This commit is contained in:
Jack Humbert 2019-06-05 00:47:31 -04:00
parent bfe468ef1d
commit f52faeb5d6
15 changed files with 6884 additions and 2348 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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(&note_array, NOTE_ARRAY_SIZE((note_array)), false)
#define PLAY_LOOP(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), true)
bool is_playing_note(void);
bool is_playing_notes(void);
#endif

View file

@ -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,75 +26,8 @@
// -----------------------------------------------------------------------------
/**
* 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
int voices = 0;
float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t dac_voices = 0;
float dac_frequencies[8] = { 0.0 };
bool playing_notes = false;
bool playing_note = false;
@ -129,7 +62,7 @@ bool glissando = true;
#endif
float startup_song[][2] = STARTUP_SONG;
static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = {
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,
@ -209,69 +142,40 @@ static const dacsample_t dac_buffer_square[DAC_BUFFER_SIZE] = {
static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = { DAC_OFF_VALUE };
#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_voice = 0;
uint8_t dac_voice_flipped = 0;
uint16_t dac_voice_counter = 0;
float dac_voice_count_flipped = 0;
static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
/**
* Generation of the sample being passed to the callback. Declared weak so users
* Generation of the waveform being passed to the callback. Declared weak so users
* can override it with their own waveforms/noises.
*/
__attribute__ ((weak))
uint16_t generate_sample(void) {
uint16_t sample = DAC_OFF_VALUE;
uint8_t working_voices = voices;
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 sample_sum = 0;
uint16_t value_avg = 0;
for (uint8_t i = 0; i < working_voices; i++) {
dac_if[i] = dac_if[i] + ((frequencies[i]*DAC_BUFFER_SIZE)/DAC_SAMPLE_RATE);
dac_if[i] = dac_if[i] + ((dac_frequencies[i] * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE);
// Needed because % doesn't work with floats
// 0.5 less than the size because we use round() later
while (dac_if[i] >= (DAC_BUFFER_SIZE))
dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE;
(void)dac_buffer;
(void)dac_buffer_square;
(void)dac_buffer_triangle;
#define DAC_MORPH_SPEED 3000
#define DAC_SAMPLE_CUSTOM_LENGTH 64
#define DAC_MORPH_SPEED_COMPUTED (DAC_SAMPLE_RATE / DAC_SAMPLE_CUSTOM_LENGTH * DAC_MORPH_SPEED / 1000)
uint16_t dac_i = (uint16_t)dac_if[i];
// Wavetable generation/lookup
uint16_t dac_i = (uint16_t)dac_if[i];
// SINE
// sample_sum += dac_buffer[dac_i] / working_voices / 3;
value_avg += dac_buffer_sine[dac_i] / working_voices / 3;
// TRIANGLE
// sample_sum += dac_buffer_triangle[dac_i] / working_voices / 3;
// RISING TRIANGLE
// sample_sum += (uint16_t)round((dac_if[i] * DAC_SAMPLE_MAX) / DAC_BUFFER_SIZE / working_voices );
value_avg += dac_buffer_triangle[dac_i] / working_voices / 3;
// SQUARE
// sample_sum += ((dac_if[i] > (DAC_BUFFER_SIZE / 2)) ? DAC_SAMPLE_MAX / working_voices: 0);
// sample_sum += dac_buffer_square[dac_i] / working_voices / 3;
// sample_sum += dac_buffer_custom[dac_voice_flipped][dac_i] / working_voices / 2 * ((dac_voice >= 63) ? 6400 - dac_voice_counter : dac_voice_counter) / 6400;
// sample_sum += dac_buffer_custom[dac_voice_flipped + 1][dac_i] / working_voices / 2 * ((dac_voice >= 63) ? dac_voice_counter : 6400 - dac_voice_counter) / 6400;
sample_sum += dac_buffer_custom[dac_voice][dac_i] / working_voices / 2 * (DAC_MORPH_SPEED_COMPUTED - dac_voice_counter) / DAC_MORPH_SPEED_COMPUTED;
sample_sum += dac_buffer_custom[dac_voice + 1][dac_i] / working_voices / 2 * dac_voice_counter / DAC_MORPH_SPEED_COMPUTED;
value_avg += dac_buffer_square[dac_i] / working_voices / 3;
}
sample = sample_sum;
dac_voice_counter++;
if (dac_voice_counter >= DAC_MORPH_SPEED_COMPUTED) {
dac_voice_counter = 0;
// dac_voice = (dac_voice + 1) % 125;
// dac_voice_flipped = ((dac_voice >= 63) ? (125 - dac_voice) : dac_voice);
dac_voice = (dac_voice + 1) % (DAC_SAMPLE_CUSTOM_LENGTH - 1);
value = value_avg;
}
}
return sample;
return value;
}
/**
@ -282,7 +186,7 @@ static void dac_end(DACDriver * dacp, dacsample_t * sample_p, size_t sample_coun
(void)dacp;
for (uint8_t s = 0; s < sample_count; s++) {
sample_p[s] = generate_sample();
sample_p[s] = dac_value_generate();
}
if (playing_notes) {
@ -402,15 +306,13 @@ void stop_all_notes() {
if (!audio_initialized) {
audio_init();
}
voices = 0;
dac_voices = 0;
playing_notes = false;
playing_note = false;
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;
}
}
@ -422,23 +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 (voices == 0) {
if (dac_voices == 0) {
playing_note = false;
}
}
@ -472,25 +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;
if (freq > 0) {
envelope_index = 0;
frequencies[voices] = freq;
dac_if[voices] = 0.0f;
volumes[voices] = vol;
voices++;
}
dac_frequencies[dac_voices] = freq;
dac_voices++;
}
}
}
__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) {
@ -517,6 +410,10 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) {
}
}
bool is_playing_note(void) {
return playing_note;
}
bool is_playing_notes(void) {
return playing_notes;
}
@ -624,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];
}

89
quantum/audio/audio_arm.h Normal file
View file

@ -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);

File diff suppressed because it is too large Load diff

39
util/sample_parser.py Normal file
View file

@ -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)

View file

@ -1,23 +0,0 @@
#! /bin/python
import wave, struct, sys
waveFile = wave.open(sys.argv[1], 'r')
length = waveFile.getnframes()
out = "static const dacsample_t dac_buffer_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)

40
util/wavetable_parser.py Normal file
View file

@ -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)