add MML tones
This commit is contained in:
parent
ac544c1790
commit
8b03bc5e84
|
|
@ -1,10 +1,8 @@
|
||||||
#nick=your nick, picked randomly on first run
|
#nick=your nick, picked randomly on first run
|
||||||
brightness=200
|
brightness=200
|
||||||
|
|
||||||
msg_freq=1800
|
tones_msg=T300 O4 l8 D l4 A+
|
||||||
msg_ms=20
|
tones_sys=T300 O4 l8 A l4 D+
|
||||||
sys_freq=440
|
|
||||||
sys_ms=10
|
|
||||||
|
|
||||||
touch_threshold=300
|
touch_threshold=300
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,21 @@ board_build.filesystem = littlefs
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
;monitor_filters = send_on_enter
|
;monitor_filters = send_on_enter
|
||||||
build_src_filter = +<meshberry/> -<chat-relay/>
|
build_src_filter =
|
||||||
|
+<meshberry/>
|
||||||
|
-<chat-relay/>
|
||||||
lib_deps =
|
lib_deps =
|
||||||
lovyan03/LovyanGFX @ ^1.2
|
lovyan03/LovyanGFX @ ^1.2
|
||||||
lvgl/lvgl @ ^9.0
|
lvgl/lvgl @ ^9.0
|
||||||
; t-vk/ESP32 BLE Keyboard@^0.3.2
|
; t-vk/ESP32 BLE Keyboard@^0.3.2
|
||||||
https://github.com/sakul-the-one/sakuls-ESP32-BLE-Keyboard
|
https://github.com/sakul-the-one/sakuls-ESP32-BLE-Keyboard
|
||||||
h2zero/NimBLE-Arduino
|
h2zero/NimBLE-Arduino
|
||||||
|
https://github.com/maxint-rd/MmlMusic
|
||||||
build_flags =
|
build_flags =
|
||||||
-DLV_CONF_INCLUDE_SIMPLE
|
-DLV_CONF_INCLUDE_SIMPLE
|
||||||
-I include
|
-I include
|
||||||
|
; use strchr instead of strchr_P
|
||||||
|
-Dstrchr_P=strchr
|
||||||
; We only need HID peripheral from NimBLE
|
; We only need HID peripheral from NimBLE
|
||||||
; saving some memory here.
|
; saving some memory here.
|
||||||
-DCONFIG_BT_NIMBLE_ROLE_CENTRAL_DISABLED
|
-DCONFIG_BT_NIMBLE_ROLE_CENTRAL_DISABLED
|
||||||
|
|
@ -39,7 +44,9 @@ board = esp32dev
|
||||||
framework = arduino
|
framework = arduino
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
build_src_filter = -<meshberry/> +<chat-relay/> ; ignores root
|
build_src_filter =
|
||||||
|
-<meshberry/>
|
||||||
|
+<chat-relay/> ; ignores meshberry
|
||||||
lib_deps =
|
lib_deps =
|
||||||
build_flags =
|
build_flags =
|
||||||
-I include
|
-I include
|
||||||
|
|
@ -403,8 +403,14 @@ void handleCommand(const char* in) {
|
||||||
ui_push_message("", "Usage: /set color_bg ff0000", false, true);
|
ui_push_message("", "Usage: /set color_bg ff0000", false, true);
|
||||||
} else {
|
} else {
|
||||||
*sp = '\0';
|
*sp = '\0';
|
||||||
if (settings_set_color(args, sp + 1))
|
size_t klen = strlen(args);
|
||||||
|
bool is_tones = klen > 6 && !strcmp(args + klen - 6, "_tones");
|
||||||
|
bool ok = is_tones ? settings_set_tones(args, sp + 1)
|
||||||
|
: settings_set_color(args, sp + 1);
|
||||||
|
if (ok)
|
||||||
ui_push_message("", "Saved. Restart to apply.", false, true);
|
ui_push_message("", "Saved. Restart to apply.", false, true);
|
||||||
|
else if (is_tones)
|
||||||
|
ui_push_message("", "Unknown tones key.", false, true);
|
||||||
else
|
else
|
||||||
ui_push_message("", "Unknown color or bad hex value.", false, true);
|
ui_push_message("", "Unknown color or bad hex value.", false, true);
|
||||||
}
|
}
|
||||||
|
|
@ -435,7 +441,7 @@ void handleCommand(const char* in) {
|
||||||
ui_push_message("", "/bt : toggle BT send mode", false, true);
|
ui_push_message("", "/bt : toggle BT send mode", false, true);
|
||||||
ui_push_message("", "/set color_bg ff0000 : set a color (restart to apply)", false, true);
|
ui_push_message("", "/set color_bg ff0000 : set a color (restart to apply)", false, true);
|
||||||
ui_push_message("", "/people : list connected", false, true);
|
ui_push_message("", "/people : list connected", false, true);
|
||||||
ui_push_message("", "/sleep : sleep device", false, true);
|
ui_push_message("", "/sleep or /s : sleep device", false, true);
|
||||||
ui_push_message("", "TAB : notes mode", false, true);
|
ui_push_message("", "TAB : notes mode", false, true);
|
||||||
//drawChatWindow();
|
//drawChatWindow();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,5 +45,6 @@ void loop() {
|
||||||
char key = Serial.available() ? (char)Serial.read() : cardkb_read();
|
char key = Serial.available() ? (char)Serial.read() : cardkb_read();
|
||||||
chat_tick(key); // TODO: debug why a serial key does not show in the UI?
|
chat_tick(key); // TODO: debug why a serial key does not show in the UI?
|
||||||
ui_tick();
|
ui_tick();
|
||||||
|
sound_tick();
|
||||||
delay(5);
|
delay(5);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
settings_t g_settings;
|
settings_t g_settings;
|
||||||
|
|
||||||
static const settings_t DEFAULTS = {
|
static const settings_t DEFAULTS = {
|
||||||
.nick = NICK_DEFAULT_PREFIX,
|
.nick = NICK_DEFAULT_PREFIX,
|
||||||
.brightness = 200,
|
.brightness = 200,
|
||||||
.msg_freq = 1800,
|
.tones_msg = "T140 G",
|
||||||
.msg_ms = 20,
|
.tones_sys = "T140 A",
|
||||||
.sys_freq = 440,
|
|
||||||
.sys_ms = 10,
|
|
||||||
.touch_threshold = TOUCH_THRESHOLD,
|
.touch_threshold = TOUCH_THRESHOLD,
|
||||||
.color_bg = {.blue = 0x11, .green = 0x11, .red = 0x11},
|
.color_bg = {.blue = 0x11, .green = 0x11, .red = 0x11},
|
||||||
.color_header_bg = {.blue = 0x1e, .green = 0x1e, .red = 0x1e},
|
.color_header_bg = {.blue = 0x1e, .green = 0x1e, .red = 0x1e},
|
||||||
|
|
@ -43,10 +42,8 @@ static bool is_hex6(const char* s) {
|
||||||
static bool apply_kv(const char* key, const char* val) {
|
static bool apply_kv(const char* key, const char* val) {
|
||||||
if (!strcmp(key, "nick")) { strncpy(g_settings.nick, val, CHAT_MAX_NICK_LEN - 1); }
|
if (!strcmp(key, "nick")) { strncpy(g_settings.nick, val, CHAT_MAX_NICK_LEN - 1); }
|
||||||
else if (!strcmp(key, "brightness")) { g_settings.brightness = (uint8_t)constrain(atoi(val), 0, 255); }
|
else if (!strcmp(key, "brightness")) { g_settings.brightness = (uint8_t)constrain(atoi(val), 0, 255); }
|
||||||
else if (!strcmp(key, "msg_freq")) { g_settings.msg_freq = (uint16_t)atoi(val); }
|
else if (!strcmp(key, "tones_msg")) { g_settings.tones_msg = String(val); }
|
||||||
else if (!strcmp(key, "msg_ms")) { g_settings.msg_ms = (uint16_t)atoi(val); }
|
else if (!strcmp(key, "tones_sys")) { g_settings.tones_sys = String(val); }
|
||||||
else if (!strcmp(key, "sys_freq")) { g_settings.sys_freq = (uint16_t)atoi(val); }
|
|
||||||
else if (!strcmp(key, "sys_ms")) { g_settings.sys_ms = (uint16_t)atoi(val); }
|
|
||||||
else if (!strcmp(key, "touch_threshold")) { g_settings.touch_threshold = (uint16_t)atoi(val); }
|
else if (!strcmp(key, "touch_threshold")) { g_settings.touch_threshold = (uint16_t)atoi(val); }
|
||||||
else if (!strcmp(key, "color_bg")) { if (!is_hex6(val)) return false; g_settings.color_bg = parse_color(val); }
|
else if (!strcmp(key, "color_bg")) { if (!is_hex6(val)) return false; g_settings.color_bg = parse_color(val); }
|
||||||
else if (!strcmp(key, "color_header_bg")) { if (!is_hex6(val)) return false; g_settings.color_header_bg = parse_color(val); }
|
else if (!strcmp(key, "color_header_bg")) { if (!is_hex6(val)) return false; g_settings.color_header_bg = parse_color(val); }
|
||||||
|
|
@ -60,12 +57,12 @@ static bool apply_kv(const char* key, const char* val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_settings() {
|
static void dump_settings() {
|
||||||
Serial.println("[settings] ---- effective config ----");
|
Serial.println("[settings]");
|
||||||
Serial.printf ("[settings] nick=%s brightness=%d\n",
|
Serial.printf ("[settings] nick=%s brightness=%d\n",
|
||||||
g_settings.nick, g_settings.brightness);
|
g_settings.nick, g_settings.brightness);
|
||||||
Serial.printf ("[settings] msg_freq=%u msg_ms=%u sys_freq=%u sys_ms=%u touch_threshold=%u\n",
|
Serial.printf ("[settings] tones_msg=%s tones_sys=%s\n",
|
||||||
g_settings.msg_freq, g_settings.msg_ms, g_settings.sys_freq,
|
g_settings.tones_msg.c_str(), g_settings.tones_sys.c_str());
|
||||||
g_settings.sys_ms, g_settings.touch_threshold);
|
Serial.printf ("[settings] touch_threshold=%u\n", g_settings.touch_threshold);
|
||||||
Serial.printf ("[settings] color_bg=%02x%02x%02x color_header_bg=%02x%02x%02x\n",
|
Serial.printf ("[settings] color_bg=%02x%02x%02x color_header_bg=%02x%02x%02x\n",
|
||||||
g_settings.color_bg.red, g_settings.color_bg.green, g_settings.color_bg.blue,
|
g_settings.color_bg.red, g_settings.color_bg.green, g_settings.color_bg.blue,
|
||||||
g_settings.color_header_bg.red, g_settings.color_header_bg.green, g_settings.color_header_bg.blue);
|
g_settings.color_header_bg.red, g_settings.color_header_bg.green, g_settings.color_header_bg.blue);
|
||||||
|
|
@ -76,7 +73,7 @@ static void dump_settings() {
|
||||||
Serial.printf ("[settings] color_system=%02x%02x%02x color_input_prompt=%02x%02x%02x\n",
|
Serial.printf ("[settings] color_system=%02x%02x%02x color_input_prompt=%02x%02x%02x\n",
|
||||||
g_settings.color_system.red, g_settings.color_system.green, g_settings.color_system.blue,
|
g_settings.color_system.red, g_settings.color_system.green, g_settings.color_system.blue,
|
||||||
g_settings.color_input_prompt.red, g_settings.color_input_prompt.green, g_settings.color_input_prompt.blue);
|
g_settings.color_input_prompt.red, g_settings.color_input_prompt.green, g_settings.color_input_prompt.blue);
|
||||||
Serial.println("[settings] ----------------------------");
|
Serial.println("[settings]");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public
|
// Public
|
||||||
|
|
@ -170,3 +167,13 @@ bool settings_set_color(const char* key, const char* hex) {
|
||||||
rewrite_config_line(key, hex);
|
rewrite_config_line(key, hex);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool settings_set_tones(const char* key, const char* tones) {
|
||||||
|
if (strlen(key) <= 6 || strcmp(key + strlen(key) - 6, "_tones") != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!apply_kv(key, tones)) return false; // unknown key or bad tones
|
||||||
|
rewrite_config_line(key, tones);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
// All values read from /config.txt on LittleFS.
|
// All values read from /config.txt on LittleFS.
|
||||||
struct settings_t {
|
struct settings_t {
|
||||||
char nick[CHAT_MAX_NICK_LEN];
|
char nick[CHAT_MAX_NICK_LEN];
|
||||||
uint8_t brightness;
|
uint8_t brightness;
|
||||||
uint16_t msg_freq; // Hz, notification beep for incoming messages
|
String tones_msg; // MML string for incoming message
|
||||||
uint16_t msg_ms; // duration in ms
|
String tones_sys; // MML string for system message
|
||||||
uint16_t sys_freq; // Hz, beep for join / leave events
|
uint16_t touch_threshold; // touch7 (GPIO27) wake-from-sleep sensitivity
|
||||||
uint16_t sys_ms; // duration in ms
|
|
||||||
uint16_t touch_threshold; // touch7 (GPIO27) wake-from-sleep sensitivity
|
|
||||||
lv_color_t color_bg;
|
lv_color_t color_bg;
|
||||||
lv_color_t color_header_bg;
|
lv_color_t color_header_bg;
|
||||||
lv_color_t color_msg;
|
lv_color_t color_msg;
|
||||||
|
|
@ -26,3 +25,4 @@ extern settings_t g_settings;
|
||||||
void settings_load();
|
void settings_load();
|
||||||
void settings_set_nick(const char* nick);
|
void settings_set_nick(const char* nick);
|
||||||
bool settings_set_color(const char* key, const char* hex);
|
bool settings_set_color(const char* key, const char* hex);
|
||||||
|
bool settings_set_tones(const char* key, const char* tones);
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,35 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <MmlMusic.h>
|
||||||
|
|
||||||
|
MmlMusic music;
|
||||||
|
|
||||||
|
static bool sound_tone_callback(unsigned int frequency, unsigned long length, uint8_t nTrack, uint8_t nVolume) {
|
||||||
|
if (frequency > 0) {
|
||||||
|
tone(PIN_SPEAKER, frequency);
|
||||||
|
} else if (length == 0) {
|
||||||
|
noTone(PIN_SPEAKER);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void sound_init() {
|
void sound_init() {
|
||||||
pinMode(PIN_SPEAKER_EN, OUTPUT);
|
pinMode(PIN_SPEAKER_EN, OUTPUT);
|
||||||
digitalWrite(PIN_SPEAKER_EN, LOW); // LOW = amp enabled
|
digitalWrite(PIN_SPEAKER_EN, LOW); // LOW = amp enabled
|
||||||
|
music.setToneCallback(sound_tone_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sound_msg_in() { tone(PIN_SPEAKER, g_settings.msg_freq, g_settings.msg_ms); }
|
void sound_tick() {
|
||||||
void sound_system() { tone(PIN_SPEAKER, g_settings.sys_freq, g_settings.sys_ms); }
|
music.continuePlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_msg_in() {
|
||||||
|
//tone(PIN_SPEAKER, g_settings.snd_msg_freq, g_settings.snd_msg_ms);
|
||||||
|
//music.play("T140 O5 O5 D L4 G L8 D G L4 B. G8 G. F#8 G. G#8 A2");
|
||||||
|
music.play(g_settings.tones_msg.c_str());
|
||||||
|
}
|
||||||
|
void sound_system() {
|
||||||
|
// tone(PIN_SPEAKER, g_settings.snd_sys_freq, g_settings.snd_sys_ms);
|
||||||
|
music.play(g_settings.tones_sys.c_str());
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void sound_init();
|
void sound_init();
|
||||||
|
void sound_tick(); // call regularly from loop() to advance MML playback
|
||||||
void sound_msg_in(); // short high beep, new chat message
|
void sound_msg_in(); // short high beep, new chat message
|
||||||
void sound_system(); // short low beep , join / leave
|
void sound_system(); // short low beep , join / leave
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue