feat(cli): use pure sine wave for CLI beep (#7444)
This commit is contained in:
+50
-6
@@ -64,6 +64,43 @@ const int16_t sineValues[] =
|
||||
15967, 15977, 15985, 15991, 15996, 15999, 16000,
|
||||
};
|
||||
|
||||
#if defined(CLI)
|
||||
// Distortion-free first-quadrant sine LUT (16000 * sin(i * (PI/2)/256)),
|
||||
// selected on demand for a clean reference tone (CLI "beep"). The default
|
||||
// sineValues[] above keeps its historical harmonics, which sound better for
|
||||
// the vario and general beeps. Only built when the CLI is enabled, so the
|
||||
// flash-constrained (no-CLI) targets don't pay for a table they never use.
|
||||
const int16_t pureSineValues[] =
|
||||
{
|
||||
0, 98, 196, 295, 393, 491, 589, 687, 785, 883,
|
||||
981, 1079, 1177, 1275, 1373, 1471, 1568, 1666, 1764, 1861,
|
||||
1959, 2056, 2153, 2251, 2348, 2445, 2542, 2639, 2735, 2832,
|
||||
2929, 3025, 3121, 3218, 3314, 3410, 3506, 3601, 3697, 3792,
|
||||
3888, 3983, 4078, 4173, 4267, 4362, 4456, 4551, 4645, 4738,
|
||||
4832, 4926, 5019, 5112, 5205, 5298, 5390, 5483, 5575, 5667,
|
||||
5758, 5850, 5941, 6032, 6123, 6214, 6304, 6394, 6484, 6573,
|
||||
6663, 6752, 6841, 6930, 7018, 7106, 7194, 7281, 7369, 7456,
|
||||
7542, 7629, 7715, 7801, 7886, 7972, 8057, 8141, 8226, 8310,
|
||||
8393, 8477, 8560, 8643, 8725, 8807, 8889, 8971, 9052, 9132,
|
||||
9213, 9293, 9373, 9452, 9531, 9610, 9688, 9766, 9844, 9921,
|
||||
9998, 10074, 10150, 10226, 10301, 10376, 10451, 10525, 10599, 10672,
|
||||
10745, 10817, 10890, 10961, 11033, 11104, 11174, 11244, 11314, 11383,
|
||||
11452, 11520, 11588, 11655, 11722, 11789, 11855, 11921, 11986, 12051,
|
||||
12115, 12179, 12243, 12306, 12368, 12430, 12492, 12553, 12614, 12674,
|
||||
12733, 12793, 12851, 12910, 12967, 13025, 13081, 13138, 13193, 13249,
|
||||
13304, 13358, 13412, 13465, 13518, 13570, 13622, 13673, 13724, 13774,
|
||||
13824, 13873, 13921, 13970, 14017, 14064, 14111, 14157, 14202, 14247,
|
||||
14292, 14335, 14379, 14422, 14464, 14506, 14547, 14587, 14627, 14667,
|
||||
14706, 14744, 14782, 14819, 14856, 14892, 14928, 14963, 14997, 15031,
|
||||
15065, 15097, 15130, 15161, 15192, 15223, 15253, 15282, 15311, 15339,
|
||||
15367, 15394, 15420, 15446, 15472, 15496, 15521, 15544, 15567, 15589,
|
||||
15611, 15632, 15653, 15673, 15693, 15711, 15730, 15747, 15764, 15781,
|
||||
15797, 15812, 15827, 15841, 15854, 15867, 15880, 15891, 15903, 15913,
|
||||
15923, 15932, 15941, 15949, 15957, 15964, 15970, 15976, 15981, 15985,
|
||||
15989, 15992, 15995, 15997, 15999, 16000, 16000,
|
||||
};
|
||||
#endif // CLI
|
||||
|
||||
#define SINE_INDEX_Q1 256
|
||||
#define SINE_INDEX_Q2 512
|
||||
#define SINE_INDEX_Q3 768
|
||||
@@ -554,17 +591,23 @@ int ToneContext::mixBuffer(AudioBuffer * buffer, int volume, unsigned int fade)
|
||||
points = (float(end) - toneIdx) / state.step;
|
||||
}
|
||||
|
||||
#if defined(CLI)
|
||||
const int16_t * sine = fragment.tone.pure ? pureSineValues : sineValues;
|
||||
#else
|
||||
const int16_t * sine = sineValues;
|
||||
#endif
|
||||
|
||||
for (int i=0; i<points; i++) {
|
||||
int16_t sineIdx = ((int)toneIdx) % MAX_SINE_INDEX;
|
||||
int16_t sineVal;
|
||||
if (sineIdx <= SINE_INDEX_Q1)
|
||||
sineVal = sineValues[sineIdx];
|
||||
sineVal = sine[sineIdx];
|
||||
else if (sineIdx <= SINE_INDEX_Q2)
|
||||
sineVal = sineValues[SINE_INDEX_Q2 - sineIdx];
|
||||
sineVal = sine[SINE_INDEX_Q2 - sineIdx];
|
||||
else if (sineIdx <= SINE_INDEX_Q3)
|
||||
sineVal = -sineValues[sineIdx - SINE_INDEX_Q2];
|
||||
sineVal = -sine[sineIdx - SINE_INDEX_Q2];
|
||||
else
|
||||
sineVal = -sineValues[MAX_SINE_INDEX - sineIdx];
|
||||
sineVal = -sine[MAX_SINE_INDEX - sineIdx];
|
||||
int16_t sample = sineVal * state.volume;
|
||||
mixSample(&buffer->data[i], sample, fade);
|
||||
toneIdx += state.step;
|
||||
@@ -714,14 +757,15 @@ void AudioQueue::playTone(uint16_t freq, uint16_t len, uint16_t pause, uint8_t f
|
||||
freq += g_eeGeneral.speakerPitch * 15;
|
||||
len = getToneLength(len);
|
||||
|
||||
bool pure = flags & PLAY_PURE;
|
||||
if (flags & PLAY_NOW) {
|
||||
if (priorityContext.isFree()) {
|
||||
priorityContext.clear();
|
||||
priorityContext.setFragment(freq, len, pause, flags & 0x0f, freqIncr, false, fragmentVolume);
|
||||
priorityContext.setFragment(freq, len, pause, flags & 0x0f, freqIncr, false, fragmentVolume, pure);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fragmentsFifo.push(AudioFragment(freq, len, pause, flags & 0x0f, freqIncr, false, fragmentVolume));
|
||||
fragmentsFifo.push(AudioFragment(freq, len, pause, flags & 0x0f, freqIncr, false, fragmentVolume, pure));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-6
@@ -133,13 +133,15 @@ struct Tone {
|
||||
uint16_t pause;
|
||||
int8_t freqIncr;
|
||||
uint8_t reset;
|
||||
uint8_t pure; // use the distortion-free sine LUT (e.g. CLI "beep")
|
||||
Tone() {};
|
||||
Tone(uint16_t freq, uint16_t duration, uint16_t pause, int8_t freqIncr, bool reset):
|
||||
Tone(uint16_t freq, uint16_t duration, uint16_t pause, int8_t freqIncr, bool reset, bool pure):
|
||||
freq(freq),
|
||||
duration(duration),
|
||||
pause(pause),
|
||||
freqIncr(freqIncr),
|
||||
reset(reset)
|
||||
reset(reset),
|
||||
pure(pure)
|
||||
{};
|
||||
};
|
||||
|
||||
@@ -155,12 +157,12 @@ struct AudioFragment {
|
||||
|
||||
AudioFragment() { clear(); };
|
||||
|
||||
AudioFragment(uint16_t freq, uint16_t duration, uint16_t pause, uint8_t repeat, int8_t freqIncr, bool reset, int8_t fragmentVolume, uint8_t id=0 ):
|
||||
AudioFragment(uint16_t freq, uint16_t duration, uint16_t pause, uint8_t repeat, int8_t freqIncr, bool reset, int8_t fragmentVolume, bool pure=false, uint8_t id=0 ):
|
||||
type(FRAGMENT_TONE),
|
||||
id(id),
|
||||
repeat(repeat),
|
||||
fragmentVolume(fragmentVolume),
|
||||
tone(freq, duration, pause, freqIncr, reset)
|
||||
tone(freq, duration, pause, freqIncr, reset, pure)
|
||||
{};
|
||||
|
||||
AudioFragment(const char * filename, uint8_t repeat, int8_t fragmentVolume, uint8_t id = 0):
|
||||
@@ -197,9 +199,9 @@ class ToneContext {
|
||||
|
||||
int mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade);
|
||||
|
||||
void setFragment(uint16_t freq, uint16_t duration, uint16_t pause, uint8_t repeat, int8_t freqIncr, bool reset, int8_t fragmentVolume, uint8_t id = 0)
|
||||
void setFragment(uint16_t freq, uint16_t duration, uint16_t pause, uint8_t repeat, int8_t freqIncr, bool reset, int8_t fragmentVolume, bool pure = false, uint8_t id = 0)
|
||||
{
|
||||
fragment = AudioFragment(freq, duration, pause, repeat, freqIncr, reset, fragmentVolume, id);
|
||||
fragment = AudioFragment(freq, duration, pause, repeat, freqIncr, reset, fragmentVolume, pure, id);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
+1
-1
@@ -253,7 +253,7 @@ int cliBeep(const char ** argv)
|
||||
int freq = BEEP_DEFAULT_FREQ;
|
||||
int duration = 100;
|
||||
if (toInt(argv, 1, &freq) >= 0 && toInt(argv, 2, &duration) >= 0) {
|
||||
audioQueue.playTone(freq, duration, 20, PLAY_NOW);
|
||||
audioQueue.playTone(freq, duration, 20, PLAY_NOW | PLAY_PURE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -461,6 +461,7 @@ extern Functions cfn_sorted[];
|
||||
#define PLAY_REPEAT(x) (x) /* Range 0 to 15 */
|
||||
#define PLAY_NOW 0x10
|
||||
#define PLAY_BACKGROUND 0x20
|
||||
#define PLAY_PURE 0x40 /* distortion-free sine */
|
||||
|
||||
enum AUDIO_SOUNDS {
|
||||
AUDIO_HELLO,
|
||||
|
||||
Reference in New Issue
Block a user