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.
This commit is contained in:
Simone Guscetti
2018-01-29 09:45:59 -05:00
committed by Daniel Agar
parent 5214642bc3
commit b84a97c6d5
2 changed files with 148 additions and 140 deletions
+135 -128
View File
@@ -52,7 +52,7 @@
// initialise default tunes // initialise default tunes
const char *Tunes::_default_tunes[] = { const char *Tunes::_default_tunes[] = {
"", // empty to align with the index "", // empty to align with the index
"MFT240L8 O2aO3dc O2aO3dc O2aO3dc L16dcdcdcdc", // startup tune "MFT240L8 O4aO5dc O4aO5dc O4aO5dc L16dcdcdcdc", // startup tune
"MBT200a8a8a8PaaaP", // ERROR tone "MBT200a8a8a8PaaaP", // ERROR tone
"MFT200e8a8a", // Notify Positive tone "MFT200e8a8a", // Notify Positive tone
"MFT200e8e", // Notify Neutral tone "MFT200e8e", // Notify Neutral tone
@@ -98,160 +98,66 @@ void Tunes::config_tone()
_octave = _default_octave; _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) { switch (tune_control.tune_id) {
case tune_control_s::STARTUP: case tune_control_s::TUNE_ID_STARTUP:
case tune_control_s::ERROR: case tune_control_s::TUNE_ID_ERROR:
case tune_control_s::NOTIFY_POSITIVE: reset_playing_tune = true;
case tune_control_s::NOTIFY_NEUTRAL: config_tone();
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:
// set tune string the first time case tune_control_s::TUNE_ID_NOTIFY_POSITIVE:
if (_tune == nullptr) { 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]; _tune = _default_tunes[tune_control.tune_id];
_next = _tune; _next = _tune;
} }
continue_sequnece = next_note(frequency, duration, silence);
break; break;
case tune_control_s::CUSTOM: case tune_control_s::TUNE_ID_CUSTOM:
default: default:
frequency = (unsigned)tune_control.frequency; _frequency = (unsigned)tune_control.frequency;
duration = (unsigned)tune_control.duration; _duration = (unsigned)tune_control.duration;
silence = 0; _using_custom_msg = true;
break; 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 // set tune string the first time
if (_tune == nullptr) { if (_tune == nullptr) {
_tune = string; _tune = string;
_next = _tune; _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 the vaules for frequency and duration if the custom msg was recieved
return (unsigned)(880.0f * powf(2.0f, ((int)note - 46) / 12.0f)); if (_using_custom_msg) {
} _using_custom_msg = false;
frequency = _frequency;
unsigned Tunes::note_duration(unsigned &silence, unsigned note_length, unsigned dots) duration = _duration;
{
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; 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 // make sure we still have a tune
if ((_next == nullptr) || (_tune == nullptr)) { if ((_next == nullptr) || (_tune == nullptr)) {
return TUNE_ERROR; return TUNE_ERROR;
@@ -441,3 +347,104 @@ tune_end:
return TUNE_STOP; 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;
}
+13 -12
View File
@@ -64,27 +64,28 @@ public:
~Tunes() = default; ~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 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), * parse a tune string, formatted with the syntax of the Microsoft GWBasic/QBasic, in frequency(Hz),
* duration(us) and silence(us). * duration(us) and silence(us).
* *
* @param string tune input string * @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 frequency return frequency value (Hz)
* @param duration return duration of the tone (us) * @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 * @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: private:
static const char *_default_tunes[TONE_NUMBER_OF_TUNES]; static const char *_default_tunes[TONE_NUMBER_OF_TUNES];
@@ -104,6 +105,10 @@ private:
NoteMode _default_mode = NoteMode::NORMAL; NoteMode _default_mode = NoteMode::NORMAL;
unsigned _default_octave = 4; unsigned _default_octave = 4;
unsigned _frequency;
unsigned _duration;
bool _using_custom_msg = false;
/** /**
* Convert note to frequency * Convert note to frequency
* *
@@ -129,10 +134,6 @@ private:
// //
unsigned rest_duration(unsigned rest_length, unsigned dots); 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 // Find the next character in the string, discard any whitespace and
// return the canonical (uppercase) version. // return the canonical (uppercase) version.
// //