From b84a97c6d5ef201889283f130555bee98db27093 Mon Sep 17 00:00:00 2001 From: Simone Guscetti Date: Mon, 27 Feb 2017 11:05:20 +0100 Subject: [PATCH] libtunes: Changed to a set_control/string and a get_next_tune functions Now it is possible to set a string and a control. The get_next_tune function use the same return values as the erliaer implemented parse_cmd and parse_string functions. --- src/lib/tunes/tunes.cpp | 263 +++++++++++++++++++++------------------- src/lib/tunes/tunes.h | 25 ++-- 2 files changed, 148 insertions(+), 140 deletions(-) diff --git a/src/lib/tunes/tunes.cpp b/src/lib/tunes/tunes.cpp index e9451125fd..e1ebd0c10e 100644 --- a/src/lib/tunes/tunes.cpp +++ b/src/lib/tunes/tunes.cpp @@ -52,7 +52,7 @@ // initialise default tunes const char *Tunes::_default_tunes[] = { "", // empty to align with the index - "MFT240L8 O2aO3dc O2aO3dc O2aO3dc L16dcdcdcdc", // startup tune + "MFT240L8 O4aO5dc O4aO5dc O4aO5dc L16dcdcdcdc", // startup tune "MBT200a8a8a8PaaaP", // ERROR tone "MFT200e8a8a", // Notify Positive tone "MFT200e8e", // Notify Neutral tone @@ -98,160 +98,66 @@ void Tunes::config_tone() _octave = _default_octave; } -int Tunes::parse_cmd(const tune_control_s &tune_control, unsigned &frequency, unsigned &duration, unsigned &silence) +void Tunes::set_control(const tune_control_s &tune_control) { - int continue_sequnece = 0; + bool reset_playing_tune = false; switch (tune_control.tune_id) { - case tune_control_s::STARTUP: - case tune_control_s::ERROR: - case tune_control_s::NOTIFY_POSITIVE: - case tune_control_s::NOTIFY_NEUTRAL: - case tune_control_s::NOTIFY_NEGATIVE: - case tune_control_s::ARMING_WARNING: - case tune_control_s::BATTERY_WARNING_SLOW: - case tune_control_s::BATTERY_WARNING_FAST: - case tune_control_s::GPS_WARNING: - case tune_control_s::PARACHUTE_RELEASE: - case tune_control_s::EKF_WARNING: - case tune_control_s::BARO_WARNING: - case tune_control_s::SINGLE_BEEP: - case tune_control_s::HOME_SET: + case tune_control_s::TUNE_ID_STARTUP: + case tune_control_s::TUNE_ID_ERROR: + reset_playing_tune = true; + config_tone(); - // set tune string the first time - if (_tune == nullptr) { + case tune_control_s::TUNE_ID_NOTIFY_POSITIVE: + case tune_control_s::TUNE_ID_NOTIFY_NEUTRAL: + case tune_control_s::TUNE_ID_NOTIFY_NEGATIVE: + case tune_control_s::TUNE_ID_ARMING_WARNING: + case tune_control_s::TUNE_ID_BATTERY_WARNING_SLOW: + case tune_control_s::TUNE_ID_BATTERY_WARNING_FAST: + case tune_control_s::TUNE_ID_GPS_WARNING: + case tune_control_s::TUNE_ID_PARACHUTE_RELEASE: + case tune_control_s::TUNE_ID_EKF_WARNING: + case tune_control_s::TUNE_ID_BARO_WARNING: + case tune_control_s::TUNE_ID_SINGLE_BEEP: + case tune_control_s::TUNE_ID_HOME_SET: + + // TODO: come up with a better strategy + if (_tune == nullptr || reset_playing_tune) { _tune = _default_tunes[tune_control.tune_id]; _next = _tune; } - continue_sequnece = next_note(frequency, duration, silence); break; - case tune_control_s::CUSTOM: + case tune_control_s::TUNE_ID_CUSTOM: default: - frequency = (unsigned)tune_control.frequency; - duration = (unsigned)tune_control.duration; - silence = 0; + _frequency = (unsigned)tune_control.frequency; + _duration = (unsigned)tune_control.duration; + _using_custom_msg = true; break; } - - return continue_sequnece; } -int Tunes::parse_string(const char *string, unsigned &frequency, unsigned &duration, unsigned &silence) +void Tunes::set_string(const char *string) { // set tune string the first time if (_tune == nullptr) { _tune = string; _next = _tune; } - - return next_note(frequency, duration, silence); } -unsigned Tunes::note_to_frequency(unsigned note) +int Tunes::get_next_tune(unsigned &frequency, unsigned &duration, unsigned &silence) { - // compute the frequency (Hz) - return (unsigned)(880.0f * powf(2.0f, ((int)note - 46) / 12.0f)); -} - -unsigned Tunes::note_duration(unsigned &silence, unsigned note_length, unsigned dots) -{ - unsigned whole_note_period = BEAT_TIME_CONVERSION / _tempo; - - if (note_length == 0) { - note_length = 1; - } - - unsigned note_period = whole_note_period / note_length; - - switch (_note_mode) { - case NoteMode::NORMAL: - silence = note_period / 8; - break; - - case NoteMode::STACCATO: - silence = note_period / 4; - break; - - case NoteMode::LEGATO: - default: + // Return the vaules for frequency and duration if the custom msg was recieved + if (_using_custom_msg) { + _using_custom_msg = false; + frequency = _frequency; + duration = _duration; silence = 0; - break; + return TUNE_STOP; } - note_period -= silence; - - unsigned dot_extension = note_period / 2; - - while (dots--) { - note_period += dot_extension; - dot_extension /= 2; - } - - return note_period; -} - -unsigned Tunes::rest_duration(unsigned rest_length, unsigned dots) -{ - unsigned whole_note_period = BEAT_TIME_CONVERSION / _tempo; - - if (rest_length == 0) { - rest_length = 1; - } - - unsigned rest_period = whole_note_period / rest_length; - - unsigned dot_extension = rest_period / 2; - - while (dots--) { - rest_period += dot_extension; - dot_extension /= 2; - } - - return rest_period; -} - -int Tunes::next_char() -{ - while (isspace(*_next)) { - _next++; - } - - return toupper(*_next); -} - -unsigned Tunes::next_number() -{ - unsigned number = 0; - int c; - - for (;;) { - c = next_char(); - - if (!isdigit(c)) { - return number; - } - - _next++; - number = (number * 10) + (c - '0'); - } -} - -unsigned Tunes::next_dots() -{ - unsigned dots = 0; - - while (next_char() == '.') { - _next++; - dots++; - } - - return dots; -} - -int Tunes::next_note(unsigned &frequency, unsigned &duration, unsigned &silence) -{ // make sure we still have a tune if ((_next == nullptr) || (_tune == nullptr)) { return TUNE_ERROR; @@ -441,3 +347,104 @@ tune_end: return TUNE_STOP; } } + +unsigned Tunes::note_to_frequency(unsigned note) +{ + // compute the frequency (Hz) + return (unsigned)(880.0f * powf(2.0f, ((int)note - 46) / 12.0f)); +} + +unsigned Tunes::note_duration(unsigned &silence, unsigned note_length, unsigned dots) +{ + unsigned whole_note_period = BEAT_TIME_CONVERSION / _tempo; + + if (note_length == 0) { + note_length = 1; + } + + unsigned note_period = whole_note_period / note_length; + + switch (_note_mode) { + case NoteMode::NORMAL: + silence = note_period / 8; + break; + + case NoteMode::STACCATO: + silence = note_period / 4; + break; + + case NoteMode::LEGATO: + default: + silence = 0; + break; + } + + note_period -= silence; + + unsigned dot_extension = note_period / 2; + + while (dots--) { + note_period += dot_extension; + dot_extension /= 2; + } + + return note_period; +} + +unsigned Tunes::rest_duration(unsigned rest_length, unsigned dots) +{ + unsigned whole_note_period = BEAT_TIME_CONVERSION / _tempo; + + if (rest_length == 0) { + rest_length = 1; + } + + unsigned rest_period = whole_note_period / rest_length; + + unsigned dot_extension = rest_period / 2; + + while (dots--) { + rest_period += dot_extension; + dot_extension /= 2; + } + + return rest_period; +} + +int Tunes::next_char() +{ + while (isspace(*_next)) { + _next++; + } + + return toupper(*_next); +} + +unsigned Tunes::next_number() +{ + unsigned number = 0; + int c; + + for (;;) { + c = next_char(); + + if (!isdigit(c)) { + return number; + } + + _next++; + number = (number * 10) + (c - '0'); + } +} + +unsigned Tunes::next_dots() +{ + unsigned dots = 0; + + while (next_char() == '.') { + _next++; + dots++; + } + + return dots; +} diff --git a/src/lib/tunes/tunes.h b/src/lib/tunes/tunes.h index a15939624b..516361d8cf 100644 --- a/src/lib/tunes/tunes.h +++ b/src/lib/tunes/tunes.h @@ -64,27 +64,28 @@ public: ~Tunes() = default; /** - * parse a tune_control_s in frequency(Hz), duration(us) and silence(us). + * Set tune to be played * * @param tune_control struct containig the uORB message - * @param frequency return frequency value (Hz) - * @param duration return duration of the tone (us) - * @param silence return silance duration (us) - * @return -1 for error, 0 for play one tone and 1 for continue a sequence */ - int parse_cmd(const tune_control_s &tune_control, unsigned &frequency, unsigned &duration, unsigned &silence); + void set_control(const tune_control_s &tune_control); /** * parse a tune string, formatted with the syntax of the Microsoft GWBasic/QBasic, in frequency(Hz), * duration(us) and silence(us). * * @param string tune input string + */ + void set_string(const char *string); + + /** + * Get next note in the setted string in set_control or play_string * @param frequency return frequency value (Hz) * @param duration return duration of the tone (us) - * @param silence return silance duration (us) + * @param silence return silence duration (us) * @return -1 for error, 0 for play one tone and 1 for continue a sequence */ - int parse_string(const char *string, unsigned &frequency, unsigned &duration, unsigned &silence); + int get_next_tune(unsigned &frequency, unsigned &duration, unsigned &silence); private: static const char *_default_tunes[TONE_NUMBER_OF_TUNES]; @@ -104,6 +105,10 @@ private: NoteMode _default_mode = NoteMode::NORMAL; unsigned _default_octave = 4; + unsigned _frequency; + unsigned _duration; + bool _using_custom_msg = false; + /** * Convert note to frequency * @@ -129,10 +134,6 @@ private: // unsigned rest_duration(unsigned rest_length, unsigned dots); - // Parse the next note out of the string - // - int next_note(unsigned &frequency, unsigned &duration, unsigned &silence); - // Find the next character in the string, discard any whitespace and // return the canonical (uppercase) version. //