Add Zira spoken button confirmations and opt-in G726 speech tests
This commit is contained in:
1 parent
5833ac2f1f
commit
8519638367
33 files changed
+11977
-30
No files matched your search
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// A compact request, not a runtime speech engine: all phrases are in flash.
|
||||
enum class ButtonVoicePrompt : uint8_t {
|
||||
Ready,
|
||||
NotificationCleared,
|
||||
AdvertQueued,
|
||||
AdvertFailed,
|
||||
SoundOn,
|
||||
SoundOff,
|
||||
GpsOn,
|
||||
GpsOff,
|
||||
ActionFailed,
|
||||
UsbSetup,
|
||||
ShuttingDown,
|
||||
Restarting,
|
||||
AlertsSoundVibration,
|
||||
AlertsSoundOnly,
|
||||
AlertsVibrationOnly,
|
||||
AlertsSilent
|
||||
};
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,175 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Decoder experiment only: production speech stays IMA until acoustic tests
|
||||
// qualify another codec. Do not enable this in release recipes yet.
|
||||
#if defined(MESH_GPS_VOICE_G726_BITRATE)
|
||||
#if !defined(MESH_BUTTON_AUDIO_HIL) || !MESH_BUTTON_AUDIO_HIL
|
||||
#error "G.726 speech is an opt-in MESH_BUTTON_AUDIO_HIL experiment"
|
||||
#endif
|
||||
#if MESH_GPS_VOICE_G726_BITRATE != 16 && MESH_GPS_VOICE_G726_BITRATE != 24
|
||||
#error "G.726 speech bitrate must be 16 or 24 kbps"
|
||||
#endif
|
||||
#include <helpers/ui/g726/g726_decoder.h>
|
||||
#endif
|
||||
|
||||
namespace mesh { namespace audio {
|
||||
|
||||
#if defined(MESH_GPS_VOICE_G726_BITRATE)
|
||||
enum class VoiceCodec : uint8_t { Ima, G72616, G72624 };
|
||||
#endif
|
||||
|
||||
// Low nibble first, independent IMA ADPCM stream starting at predictor/index 0.
|
||||
// The samples live in flash; playback only needs two small DMA buffers in RAM.
|
||||
struct VoiceClip {
|
||||
const uint8_t* data;
|
||||
size_t bytes;
|
||||
uint32_t samples;
|
||||
uint32_t sample_rate;
|
||||
#if defined(MESH_GPS_VOICE_G726_BITRATE)
|
||||
VoiceCodec codec;
|
||||
constexpr VoiceClip(const uint8_t* data = nullptr, size_t bytes = 0,
|
||||
uint32_t samples = 0, uint32_t sample_rate = 8000,
|
||||
VoiceCodec codec = VoiceCodec::Ima)
|
||||
: data(data), bytes(bytes), samples(samples), sample_rate(sample_rate), codec(codec) {}
|
||||
unsigned bits() const {
|
||||
if (codec == VoiceCodec::Ima) return 4;
|
||||
#if MESH_GPS_VOICE_G726_BITRATE == 16
|
||||
if (codec == VoiceCodec::G72616) return 2;
|
||||
#else
|
||||
if (codec == VoiceCodec::G72624) return 3;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
// Divide before multiplying: valid even for UINT32_MAX sample counts and
|
||||
// SIZE_MAX byte counts. The final byte may contain unused padding bits.
|
||||
size_t requiredBytes(uint32_t count) const {
|
||||
const unsigned b = bits();
|
||||
return (count / 8) * b + ((count % 8) * b + 7) / 8;
|
||||
}
|
||||
bool valid() const {
|
||||
return data && samples && bits() && bytes >= requiredBytes(samples)
|
||||
&& (codec == VoiceCodec::Ima ? (sample_rate == 8000 || sample_rate == 16000)
|
||||
: sample_rate == 8000);
|
||||
}
|
||||
#else
|
||||
constexpr VoiceClip(const uint8_t* data = nullptr, size_t bytes = 0,
|
||||
uint32_t samples = 0, uint32_t sample_rate = 8000)
|
||||
: data(data), bytes(bytes), samples(samples), sample_rate(sample_rate) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
class VoiceDecoder {
|
||||
VoiceClip clip_ = {};
|
||||
uint32_t position_ = 0;
|
||||
int32_t predictor_ = 0;
|
||||
int index_ = 0;
|
||||
#if defined(MESH_GPS_VOICE_G726_BITRATE)
|
||||
G726State g726_ = {};
|
||||
#endif
|
||||
public:
|
||||
void begin(VoiceClip clip) {
|
||||
clip_ = clip;
|
||||
position_ = 0;
|
||||
predictor_ = 0;
|
||||
index_ = 0;
|
||||
#if defined(MESH_GPS_VOICE_G726_BITRATE)
|
||||
g726_init(&g726_);
|
||||
#endif
|
||||
}
|
||||
uint32_t position() const { return position_; }
|
||||
bool done() const {
|
||||
#if defined(MESH_GPS_VOICE_G726_BITRATE)
|
||||
return !clip_.data || !clip_.bits() || position_ >= clip_.samples
|
||||
|| clip_.requiredBytes(position_ + 1) > clip_.bytes;
|
||||
#else
|
||||
return !clip_.data || position_ >= clip_.samples
|
||||
|| position_ / 2 >= clip_.bytes;
|
||||
#endif
|
||||
}
|
||||
int16_t next() {
|
||||
static const int16_t steps[89] = {
|
||||
7,8,9,10,11,12,13,14,16,17,19,21,23,25,28,31,34,37,41,45,50,55,
|
||||
60,66,73,80,88,97,107,118,130,143,157,173,190,209,230,253,279,
|
||||
307,337,371,408,449,494,544,598,658,724,796,876,963,1060,1166,
|
||||
1282,1411,1552,1707,1878,2066,2272,2499,2749,3024,3327,3660,
|
||||
4026,4428,4871,5358,5894,6484,7132,7845,8630,9493,10442,11487,
|
||||
12635,13899,15289,16818,18500,20350,22385,24623,27086,29794,32767
|
||||
};
|
||||
static const int8_t adjustments[8] = {-1,-1,-1,-1,2,4,6,8};
|
||||
if (done()) return 0;
|
||||
#if defined(MESH_GPS_VOICE_G726_BITRATE)
|
||||
if (clip_.codec != VoiceCodec::Ima) {
|
||||
const unsigned bits = clip_.bits();
|
||||
const unsigned bit = ((position_ % 8) * bits) % 8;
|
||||
const size_t byte = (position_ / 8) * bits + ((position_ % 8) * bits) / 8;
|
||||
unsigned word = clip_.data[byte];
|
||||
unsigned shift;
|
||||
if (bit + bits > 8) {
|
||||
word = (word << 8) | clip_.data[byte + 1];
|
||||
shift = 16 - bit - bits;
|
||||
} else shift = 8 - bit - bits;
|
||||
++position_;
|
||||
return g726_decode(&g726_, (word >> shift) & ((1u << bits) - 1), bits);
|
||||
}
|
||||
#endif
|
||||
const uint8_t code = (clip_.data[position_ / 2]
|
||||
>> ((position_ & 1) * 4)) & 15;
|
||||
++position_;
|
||||
const int32_t step = steps[index_];
|
||||
int32_t delta = step >> 3;
|
||||
if (code & 1) delta += step >> 2;
|
||||
if (code & 2) delta += step >> 1;
|
||||
if (code & 4) delta += step;
|
||||
predictor_ += (code & 8) ? -delta : delta;
|
||||
if (predictor_ > 32767) predictor_ = 32767;
|
||||
if (predictor_ < -32768) predictor_ = -32768;
|
||||
index_ += adjustments[code & 7];
|
||||
if (index_ < 0) index_ = 0;
|
||||
if (index_ > 88) index_ = 88;
|
||||
return static_cast<int16_t>(predictor_);
|
||||
}
|
||||
};
|
||||
|
||||
// Reconstruction at 32 kHz, without larger clips or allocations. Four phases
|
||||
// suppress 8 kHz sampling images (3.2 kHz cutoff, Kaiser beta=7). Two phases
|
||||
// retain the consonant band of 16 kHz clips (7.2 kHz cutoff, Kaiser beta=5).
|
||||
// Each phase has exactly unity DC gain (Q14).
|
||||
class VoiceInterpolator {
|
||||
int16_t history_[16] = {};
|
||||
unsigned head_ = 0;
|
||||
unsigned phase_ = 0;
|
||||
unsigned phases_ = 4;
|
||||
public:
|
||||
void begin(uint32_t sample_rate = 8000) {
|
||||
for (auto& sample : history_) sample = 0;
|
||||
head_ = phase_ = 0;
|
||||
phases_ = sample_rate == 16000 ? 2 : 4;
|
||||
}
|
||||
int32_t next(VoiceDecoder& decoder) {
|
||||
static const int16_t coefficients[4][16] = {
|
||||
{3,-31,86,-84,-181,940,-2310,4633,12885,1341,-1562,983,-394,67,25,-17},
|
||||
{2,-35,137,-268,216,424,-2259,8176,11169,-1061,-502,671,-404,141,-19,-4},
|
||||
{-4,-19,141,-404,671,-502,-1061,11169,8176,-2259,424,216,-268,137,-35,2},
|
||||
{-17,25,67,-394,983,-1562,1341,12885,4633,-2310,940,-181,-84,86,-31,3}
|
||||
};
|
||||
static const int16_t wide_coefficients[2][16] = {
|
||||
{2,21,-113,332,-739,1415,-2581,5802,13506,-1505,150,249,-311,238,-133,51},
|
||||
{51,-133,238,-311,249,150,-1505,13506,5802,-2581,1415,-739,332,-113,21,2}
|
||||
};
|
||||
if (!phase_) {
|
||||
head_ = (head_ + 1) & 15;
|
||||
history_[head_] = decoder.next();
|
||||
}
|
||||
int32_t value = 0;
|
||||
const int16_t* taps = phases_ == 2 ? wide_coefficients[phase_] : coefficients[phase_];
|
||||
for (unsigned i = 0; i < 16; ++i)
|
||||
value += static_cast<int32_t>(history_[(head_ - i) & 15]) * taps[i];
|
||||
phase_ = (phase_ + 1) & (phases_ - 1);
|
||||
return value / 16384;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace mesh::audio
|
||||
@@ -0,0 +1,491 @@
|
||||
// Generated by scripts/generate_gps_voice.py. 8 kHz IMA ADPCM.
|
||||
// Phrases: "GPS on", "GPS off". No runtime speech engine.
|
||||
// Voice: Microsoft Zira Desktop
|
||||
#pragma once
|
||||
#include <helpers/ui/GpsVoice.h>
|
||||
namespace mesh { namespace audio {
|
||||
static const uint8_t gpsOnData[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,
|
||||
0x7f,0xf7,0xf7,0x61,0x5c,0x8b,0xd1,0x04,0x4a,0x8c,0xb3,0x83,0x90,0x98,0x91,0x22,0x2d,0x89,0x28,0xd1,
|
||||
0xa3,0x20,0x0a,0x80,0xf1,0xb7,0x01,0x5d,0x1a,0x88,0x91,0x18,0x2a,0xa0,0xb5,0x81,0x38,0x2c,0x88,0x2b,
|
||||
0x5a,0xb9,0xa7,0xa1,0xb4,0xc3,0x51,0x1d,0x08,0x90,0x20,0x3c,0x1b,0xf3,0xa3,0x81,0x28,0x1b,0x98,0xb4,
|
||||
0x82,0x6c,0x8a,0xc3,0xc4,0x11,0x09,0x00,0x0a,0xb1,0xa5,0x20,0x2c,0x39,0x4f,0x8a,0xa2,0x01,0x5b,0x0a,
|
||||
0xc1,0xb6,0x82,0x4a,0x8a,0xb2,0x02,0x5c,0x1b,0xa1,0xa2,0x01,0x3a,0x2a,0x3b,0x99,0xf7,0xa3,0x30,0x2d,
|
||||
0x19,0x29,0x2c,0xc0,0xb5,0x21,0x3c,0x2b,0xc0,0xb4,0xb4,0x11,0x2a,0x1a,0x98,0x82,0x3a,0x89,0x10,0xb9,
|
||||
0xb7,0x82,0x5a,0x2b,0xe0,0xc6,0x82,0x49,0x2c,0x89,0xc3,0x82,0x29,0x4b,0x8a,0xd4,0xa3,0x20,0x4d,0x0a,
|
||||
0xc2,0x82,0x29,0x2b,0xb0,0xb5,0x02,0x4b,0x3b,0x8a,0xd4,0xb4,0x01,0x29,0x4b,0x2b,0xd0,0xb6,0x82,0x39,
|
||||
0x2c,0x89,0xb2,0xa3,0x10,0x1a,0x90,0xa2,0x50,0x2e,0xe1,0xb4,0x02,0x5c,0x2b,0x89,0xa2,0x01,0x19,0x09,
|
||||
0xc2,0x11,0x3b,0x4c,0xa9,0xb5,0x11,0x5b,0x1b,0xc1,0x83,0x5b,0x0a,0xc2,0x82,0x39,0x2c,0x88,0x29,0x89,
|
||||
0x93,0x4d,0x99,0xe6,0xb5,0x82,0x5b,0x2b,0x98,0xc3,0x82,0x49,0x3d,0x99,0xc4,0x82,0x39,0x3d,0x99,0xc3,
|
||||
0x93,0x39,0x2c,0x09,0xb1,0xa4,0x10,0x3b,0x89,0xb2,0x12,0x3d,0xc8,0xb5,0x21,0x4f,0x2b,0xa0,0xb3,0x92,
|
||||
0x18,0x19,0x4a,0x3c,0x0a,0x00,0x3a,0x0a,0xf5,0xc5,0x21,0x3d,0x0a,0xa1,0xa3,0x80,0xb1,0x03,0x6e,0x2c,
|
||||
0x98,0xb3,0x92,0x00,0x5b,0x1a,0x88,0x00,0x19,0x98,0xc6,0x21,0x4f,0x0a,0xa0,0xb4,0x82,0x08,0x19,0x08,
|
||||
0x4a,0x1a,0x29,0xb8,0xb4,0xc5,0x21,0x3c,0x4b,0x9a,0xc5,0x82,0x39,0x3d,0x0a,0xb1,0xa4,0x81,0x18,0x2a,
|
||||
0xa8,0xa4,0x28,0xb0,0x31,0x2e,0xa0,0xc3,0xb3,0x70,0x4f,0x0a,0xc1,0xa3,0x20,0x4d,0x1a,0xb0,0xa5,0x10,
|
||||
0x4b,0x0a,0xa1,0xc3,0x82,0x19,0x19,0xa0,0x11,0x3b,0x1b,0xf5,0xa3,0x10,0x4c,0x0a,0x80,0x30,0x9a,0xb7,
|
||||
0x11,0x2c,0x8a,0xb0,0xb2,0x21,0x6c,0x19,0x91,0x93,0x02,0x29,0x2b,0x0b,0x8b,0xf8,0x24,0x3f,0xc0,0xa3,
|
||||
0x88,0x8a,0x1a,0x9a,0xa4,0x13,0x32,0x34,0x50,0x18,0x98,0xd1,0xb0,0x99,0x1f,0xb3,0x78,0x2b,0xd1,0x00,
|
||||
0x0c,0xa8,0x00,0x18,0x12,0x52,0x12,0x32,0x39,0xb9,0xd0,0xaa,0xcb,0x2a,0xf3,0x04,0x5c,0x9a,0xb2,0x19,
|
||||
0x9b,0x91,0x30,0x41,0x62,0x21,0x83,0x11,0x1c,0xbb,0xe8,0x99,0x59,0x2d,0xc1,0x83,0x2c,0xaa,0xb1,0x08,
|
||||
0x00,0x42,0x51,0x03,0x15,0x10,0x89,0xa9,0xca,0xba,0x0c,0xf2,0x12,0x4d,0xb8,0xb4,0x39,0x0c,0x90,0x11,
|
||||
0x20,0x14,0x42,0x20,0x91,0xb1,0xc9,0xca,0xab,0x6b,0x1d,0xe2,0x83,0x3b,0x9b,0xb2,0x18,0x90,0x06,0x60,
|
||||
0x10,0x83,0x11,0x0a,0xb8,0x9b,0x9e,0x1a,0xd9,0xb7,0x30,0x1d,0xc0,0x92,0x29,0x09,0x11,0x31,0x13,0x15,
|
||||
0x30,0x1a,0xb9,0xf9,0xb8,0x8a,0xe2,0x12,0x3e,0xc9,0xb4,0x39,0x1c,0x90,0x02,0x12,0x14,0x42,0x28,0x98,
|
||||
0xc1,0xa9,0x9c,0x0c,0xf2,0x83,0x4c,0xa9,0xc3,0x18,0x8a,0x81,0x40,0x38,0x13,0x24,0x01,0xa2,0x98,0x9e,
|
||||
0xca,0x99,0xf3,0x83,0x4d,0xa9,0xd3,0x10,0x1b,0xa0,0x84,0x31,0x21,0x42,0x28,0xb0,0xd3,0x1a,0x0f,0x0a,
|
||||
0xd1,0xb5,0x20,0x1d,0xa8,0x92,0x19,0x08,0x12,0x60,0x01,0x94,0x12,0x3c,0xab,0xf2,0x80,0x4a,0x1c,0xc1,
|
||||
0xa4,0x39,0x0c,0xa0,0x81,0x18,0x01,0x33,0x70,0x08,0xb3,0x82,0x1c,0x8c,0xc8,0xb3,0x58,0x1c,0xb0,0x81,
|
||||
0x1d,0xb8,0x93,0x69,0x18,0x85,0x22,0x28,0xa0,0xc2,0x89,0x9c,0xa9,0xc5,0x12,0x3d,0x9a,0xd2,0x08,0x8a,
|
||||
0xa2,0x32,0x40,0x14,0x33,0x38,0xb0,0xe2,0x0a,0x8f,0x00,0x3b,0xf0,0xb4,0x38,0x1e,0xb0,0xa3,0x20,0x29,
|
||||
0x12,0x41,0x18,0xb3,0x92,0x2d,0x8d,0x99,0xd3,0x83,0x4c,0x8b,0xb0,0x19,0x8c,0xb2,0x24,0x79,0x10,0x03,
|
||||
0x82,0x81,0x09,0x0e,0xab,0x01,0x3c,0xf0,0xa4,0x4a,0x0d,0xb0,0x82,0x18,0x81,0x14,0x50,0x18,0x91,0xa2,
|
||||
0x09,0x0d,0x8b,0xf4,0x93,0x6b,0x0b,0xc1,0x81,0x1a,0x98,0x12,0x48,0x01,0x85,0x12,0x08,0x98,0x0a,0x0f,
|
||||
0x88,0x09,0xe1,0xb3,0x4a,0x0d,0xa8,0x81,0x28,0x01,0x15,0x60,0x18,0xa2,0x82,0x0b,0xca,0x88,0xb0,0x94,
|
||||
0x5d,0x0c,0xc0,0xa1,0x88,0x08,0x30,0x30,0x86,0x86,0x21,0x19,0x89,0xa9,0xd9,0x82,0x4e,0x9a,0xc3,0x00,
|
||||
0x1c,0x99,0x00,0x4a,0x00,0x85,0x32,0x38,0x81,0x92,0x8a,0xad,0xc9,0xa3,0x7b,0x1c,0xe2,0x81,0x2b,0x9b,
|
||||
0xc3,0x31,0x5a,0x01,0x04,0x21,0x18,0x98,0x99,0xbb,0x9b,0xf3,0x02,0x5f,0x8b,0xe2,0x81,0x2a,0x0a,0x81,
|
||||
0x12,0x12,0x24,0x40,0x29,0x99,0xf1,0xa0,0x1a,0xa8,0x93,0x5d,0x8b,0xe2,0x00,0x2b,0x8a,0x93,0x04,0x32,
|
||||
0x61,0x28,0x91,0xb2,0xa0,0x0d,0x9c,0xc3,0x58,0x2d,0xc0,0x92,0x2b,0x9b,0xc3,0x31,0x5a,0x01,0x14,0x31,
|
||||
0x08,0xa1,0x99,0x9d,0xba,0x3b,0xbb,0xc7,0x33,0x2f,0xaa,0xd3,0x00,0x2a,0x08,0x03,0x43,0x31,0x12,0x10,
|
||||
0x9a,0xf9,0xb8,0x8b,0x4c,0x1b,0xe5,0x83,0x4c,0x8b,0xc1,0x01,0x2a,0x00,0x31,0x30,0x85,0x13,0x4b,0xaa,
|
||||
0xd1,0x99,0x8b,0x3a,0x2c,0xe5,0x83,0x5b,0x9b,0xd3,0x00,0x1a,0x81,0x13,0x31,0x04,0x32,0x1a,0xe0,0xa0,
|
||||
0x0d,0x9b,0x08,0xd2,0x85,0x6a,0x8a,0xd2,0x00,0x1b,0x98,0x82,0x22,0x41,0x41,0x11,0x92,0x88,0x8c,0xbc,
|
||||
0xb9,0xaa,0x42,0x5d,0xb1,0x84,0x2b,0xbb,0xe1,0x08,0x2a,0x10,0x15,0x43,0x31,0x11,0xa1,0xa8,0xad,0xac,
|
||||
0xba,0x9a,0x87,0x58,0x88,0xa2,0x09,0x8d,0xba,0xa0,0x48,0x48,0x23,0x17,0x31,0x00,0xa1,0xa8,0x9d,0xbb,
|
||||
0xca,0x09,0x42,0x38,0x85,0x91,0x0a,0xaf,0xc8,0x89,0x19,0x11,0x25,0x34,0x42,0x11,0x81,0x98,0xac,0xdb,
|
||||
0xba,0x9a,0x39,0x12,0x25,0x21,0x80,0xd8,0xca,0xbb,0x8c,0xa8,0xa8,0x72,0x43,0x24,0x32,0x21,0x00,0x99,
|
||||
0xcb,0xbc,0xab,0xa9,0x00,0x08,0x80,0xa1,0xaa,0xbd,0xdb,0xa9,0x0a,0x30,0x44,0x35,0x34,0x24,0x23,0x12,
|
||||
0x81,0xa8,0xbb,0x09,0x8b,0xb9,0xfb,0xbd,0xbd,0xdb,0xaa,0x9b,0x89,0x11,0x44,0x53,0x33,0x24,0x23,0x12,
|
||||
0x00,0xa8,0xba,0x9d,0x91,0x18,0x80,0xb8,0xdc,0xbc,0xcd,0xba,0xba,0x9a,0x18,0x41,0x44,0x43,0x24,0x33,
|
||||
0x32,0x21,0x80,0xa8,0x1b,0xc9,0xa8,0xdb,0xcb,0xad,0xdb,0xaa,0xab,0x9a,0x88,0x30,0x52,0x34,0x34,0x34,
|
||||
0x32,0x23,0x22,0x01,0xa1,0x35,0x1b,0xa8,0xcc,0xbd,0xbd,0xdb,0xaa,0xab,0x9a,0x89,0x11,0x35,0x63,0x42,
|
||||
0x32,0x32,0x32,0x12,0x01,0xb0,0x54,0x8d,0xa8,0xdb,0xbb,0xbc,0xac,0xaa,0x99,0x00,0x33,0x45,0x53,0x32,
|
||||
0x23,0x14,0x02,0x81,0xa8,0xba,0xcd,0x21,0x9f,0xa8,0xc9,0xa9,0xaa,0xa9,0x10,0x41,0x51,0x43,0x23,0x24,
|
||||
0x23,0x12,0x00,0xa9,0xcc,0xda,0xba,0xda,0x32,0x0e,0x08,0x99,0xa9,0x80,0x88,0x41,0x32,0x34,0x43,0x33,
|
||||
0x32,0x93,0xb1,0xda,0xdb,0xca,0xaa,0xdb,0xb8,0x67,0x0a,0x00,0x08,0xba,0x29,0xba,0xb5,0x87,0x08,0x01,
|
||||
0x08,0x11,0xa5,0x21,0x1e,0xa8,0xa0,0xa2,0x1b,0x31,0x88,0xf1,0x38,0xc0,0x12,0x91,0x70,0x80,0x98,0x19,
|
||||
0x8b,0xa2,0x5c,0xc0,0x80,0x21,0x18,0x79,0xa8,0x97,0xa2,0x19,0x9b,0xa9,0x0a,0x8e,0x7b,0xa1,0x81,0x20,
|
||||
0x19,0x88,0x07,0x88,0x1a,0x14,0x3a,0x59,0xc8,0x90,0x82,0x9d,0x00,0x89,0xe1,0x13,0x28,0x3d,0x89,0x80,
|
||||
0x11,0x09,0xf9,0x89,0x29,0xe4,0x08,0x83,0x49,0x5a,0x90,0x18,0xb1,0x29,0x4b,0x90,0x11,0xb3,0x1f,0x1a,
|
||||
0x99,0x18,0xb9,0xb2,0x87,0x41,0x69,0x00,0x19,0x0b,0xcb,0xaa,0xb7,0x11,0x00,0x90,0x9e,0x80,0x42,0x8d,
|
||||
0x30,0xa0,0xa6,0x04,0x0a,0x00,0x99,0x01,0xd3,0x21,0x1f,0x89,0xa0,0x08,0x18,0x02,0x02,0x51,0x95,0x22,
|
||||
0x89,0x8f,0xc1,0x90,0x19,0x91,0xa8,0x5b,0x3d,0x98,0x02,0xa2,0x1f,0x9a,0x96,0x02,0x2a,0x11,0x42,0x5a,
|
||||
0x08,0xb1,0x00,0xa8,0x9f,0xc2,0xa9,0xa0,0x8e,0x21,0x6b,0x10,0x83,0x1a,0x11,0xb0,0x82,0xd1,0x90,0x30,
|
||||
0x4c,0x09,0xa3,0x9a,0xc8,0xf1,0xb8,0x07,0x1b,0x89,0xb3,0x91,0x70,0x09,0x81,0x6a,0xb2,0x2d,0x14,0xb9,
|
||||
0x33,0xf9,0x38,0xa9,0x9a,0x10,0x1c,0x93,0x7b,0xb1,0x18,0x04,0xf0,0x7f,0xb1,0x3a,0x08,0x9a,0x07,0x0b,
|
||||
0xa6,0x0a,0x12,0x0a,0x80,0xf3,0x21,0x1a,0x2f,0xb0,0x01,0x93,0x1a,0x0a,0x8a,0x17,0x5d,0xa0,0xaa,0x07,
|
||||
0x3d,0x88,0x00,0x88,0x2a,0xc0,0x95,0x29,0x18,0x0f,0xa4,0x90,0x02,0x48,0x9d,0x05,0x0d,0xa4,0x3b,0xb1,
|
||||
0x38,0xc1,0x01,0x92,0x5b,0xa9,0x95,0x3a,0x08,0x1e,0xc4,0x28,0x88,0x08,0xb4,0x80,0x58,0x8d,0x94,0x0a,
|
||||
0x93,0x5d,0xc0,0x21,0xb8,0x22,0x0b,0xb1,0x41,0xac,0x14,0x1d,0x92,0x98,0x83,0x4e,0xa8,0x11,0xb8,0x22,
|
||||
0x8c,0x01,0x09,0x28,0xc2,0x7a,0xe8,0x84,0x88,0x39,0xb8,0x11,0xf1,0x22,0x2e,0x90,0x08,0xb2,0x30,0xaa,
|
||||
0x12,0x1d,0xc3,0x11,0xa9,0xa7,0x49,0xaa,0xa6,0x38,0x8a,0x10,0xa9,0xa5,0x49,0x0a,0x81,0x2a,0xe1,0x94,
|
||||
0x39,0x0a,0x29,0xd8,0xa6,0x10,0x1a,0x90,0x28,0xa8,0x93,0x88,0x90,0x20,0x9c,0xc7,0x21,0x89,0x30,0x1d,
|
||||
0x98,0xc5,0x11,0x0a,0x38,0x2d,0xd1,0xa4,0x28,0x1a,0x19,0xd2,0x02,0x4c,0x0a,0xa2,0x18,0xc0,0xb5,0x02,
|
||||
0x5b,0x2b,0x99,0xd6,0x93,0x28,0x2b,0x19,0x1a,0xe2,0xb4,0x82,0x4a,0x1b,0xd1,0xb4,0x12,0x4c,0x0a,0xa0,
|
||||
0xb4,0x02,0x5b,0x2b,0x09,0xb0,0xb7,0xa3,0x38,0x3d,0x0a,0x90,0x91,0xb3,0x40,0x2c,0x89,0xa1,0x02,0xa8,
|
||||
0x31,0x3c,0xc8,0xb7,0x81,0x00,0x4c,0x8a,0xa2,0x20,0xb8,0x44,0x3f,0xb9,0xb6,0x01,0x2a,0x88,0x6a,0x1b,
|
||||
0xb1,0xc6,0x93,0x38,0x3e,0x0a,0xb1,0xa3,0x18,0x18,0x19,0x4a,0x8a,0x21,0x1e,0xe2,0xb5,0x20,0x3b,0x0a,
|
||||
0x00,0xc0,0xa5,0x01,0x6b,0x2c,0x19,0x88,0xc2,0xb3,0x31,0x1f,0x80,0x08,0x80,0xb1,0xb4,0x42,0x3e,0x89,
|
||||
0x90,0x88,0xc1,0xa3,0x48,0x3c,0x09,0x91,0x01,0x90,0x92,0x38,0x3c,0x9a,0x17,0x7a,0x0a,0xc0,0x80,0x0c,
|
||||
0xa9,0xa2,0x11,0x20,0x22,0x51,0x10,0xa2,0xb3,0x80,0x3c,0xb7,0x51,0x2f,0xa9,0x91,0x8a,0xc8,0xb3,0x40,
|
||||
0x4b,0x00,0x03,0x11,0xa2,0xa4,0x18,0x4f,0xa8,0xa5,0x18,0x8b,0xd8,0x90,0x0a,0x89,0x02,0x51,0x30,0x03,
|
||||
0x14,0x38,0x1b,0xab,0x7a,0xb8,0xc7,0x82,0x2d,0x9b,0xb0,0x08,0x09,0x02,0x53,0x58,0x01,0x83,0x10,0x8a,
|
||||
0xd8,0x22,0x3f,0xb9,0xc5,0x08,0x8b,0xb8,0x00,0x4a,0x00,0x05,0x41,0x28,0x81,0x81,0x1a,0x0c,0xe5,0x93,
|
||||
0x5b,0x8c,0xa0,0x88,0x8a,0xc2,0x13,0x7a,0x18,0x82,0x12,0x19,0x98,0x98,0x48,0x3e,0xc9,0xc3,0x09,0x8c,
|
||||
0xb8,0x10,0x4a,0x81,0x87,0x22,0x38,0x80,0x91,0x8a,0x0c,0xf3,0x83,0x3d,0x9b,0xf2,0x80,0x2b,0x99,0x83,
|
||||
0x50,0x10,0x04,0x21,0x29,0xb8,0xd1,0x20,0x2e,0xc8,0xc3,0x19,0x0d,0xa8,0x00,0x39,0x00,0x06,0x31,0x38,
|
||||
0x91,0x92,0x0a,0x1e,0xf3,0xa3,0x39,0x0e,0xb8,0x09,0x0b,0xb1,0x85,0x41,0x30,0x22,0x40,0x09,0xe1,0xb1,
|
||||
0x58,0x2e,0xa8,0xc3,0x18,0x0c,0xa8,0x28,0x4c,0x88,0x95,0x22,0x39,0x80,0x81,0x1a,0x8c,0xf5,0xa3,0x39,
|
||||
0x0d,0xa8,0x80,0x1a,0xb0,0x96,0x31,0x39,0x02,0x03,0x38,0x0c,0xb9,0x21,0x3f,0xcb,0xd6,0x00,0x1b,0xa9,
|
||||
0x92,0x59,0x3a,0x92,0x86,0x02,0x00,0x00,0x1b,0x1c,0xf1,0xb3,0x38,0x1e,0xa9,0x90,0x1a,0x89,0x93,0x14,
|
||||
0x32,0x24,0x32,0x39,0xb8,0xf2,0xd4,0x20,0x2f,0x9a,0xb1,0x08,0x8b,0xb2,0x13,0x50,0x11,0x05,0x21,0x08,
|
||||
0xb1,0x98,0x7a,0x3e,0xaa,0xd4,0x91,0x1a,0x8a,0x88,0x39,0x10,0x96,0x85,0x21,0x18,0x80,0x09,0x5c,0x0b,
|
||||
0xf3,0x91,0x1a,0x8c,0x98,0x19,0x19,0xa3,0x07,0x31,0x48,0x18,0x90,0xb1,0x88,0xf2,0xa3,0x5c,0x0d,0xc0,
|
||||
0xa2,0x08,0x09,0x92,0x32,0x58,0x01,0x83,0x20,0x1c,0xd8,0xc5,0x11,0x3d,0x9b,0xb1,0x08,0x0b,0xc1,0x84,
|
||||
0x40,0x38,0x11,0x02,0x92,0xc2,0xa1,0x91,0x6c,0x1e,0xa9,0xc1,0x88,0x9a,0xb2,0x32,0x7a,0x01,0x95,0x13,
|
||||
0x29,0x89,0x98,0xb3,0x6a,0x1e,0xc9,0xc2,0x08,0x0b,0x88,0x21,0x79,0x00,0x84,0x02,0x10,0x89,0x98,0x91,
|
||||
0x7b,0x1e,0xc8,0xc2,0x80,0x1a,0x09,0x01,0x31,0x31,0x04,0x04,0x48,0x1b,0xe8,0xb5,0x20,0x2f,0x9a,0xb1,
|
||||
0x08,0x0a,0xa1,0x84,0x60,0x29,0x82,0x03,0x28,0x8a,0xb8,0xd6,0x92,0x3b,0x0f,0xa8,0x90,0x09,0xa0,0x95,
|
||||
0x42,0x59,0x00,0x92,0x01,0x89,0x39,0x0c,0xf1,0xc2,0x88,0x8b,0x8a,0x1a,0x18,0x04,0x15,0x23,0x13,0x22,
|
||||
0x3a,0x8e,0x81,0x4c,0x9c,0xf1,0xa0,0x0a,0x1b,0x09,0x11,0x32,0x35,0x33,0x13,0x02,0x89,0x1f,0xf1,0xc3,
|
||||
0x29,0x0f,0xa8,0xa1,0x28,0x2a,0x92,0x15,0x40,0x18,0x92,0x92,0x89,0x28,0x2f,0xca,0xf4,0x91,0x2a,0x0b,
|
||||
0x90,0x83,0x22,0x31,0x22,0x32,0x29,0x9a,0x8b,0xf6,0xa2,0x3c,0x8e,0xc0,0x80,0x2a,0xa0,0x86,0x31,0x59,
|
||||
0x80,0x92,0x81,0x8a,0x80,0x4c,0x8c,0xf1,0xa1,0x09,0x0a,0x90,0x12,0x51,0x40,0x10,0x93,0x93,0x09,0x1d,
|
||||
0xf2,0xb3,0x3a,0x8f,0xb0,0xa1,0x29,0x08,0x04,0x42,0x48,0x81,0x93,0x08,0xab,0x82,0x4f,0x9c,0xf3,0x80,
|
||||
0x1a,0x99,0x82,0x30,0x48,0x02,0x85,0x01,0x19,0x8a,0x9a,0xe6,0x93,0x4b,0x8c,0xc0,0x80,0x09,0x91,0x23,
|
||||
0x70,0x10,0x82,0x01,0x0a,0xba,0x82,0x3f,0xab,0xf3,0x08,0x0b,0xa8,0x11,0x30,0x04,0x25,0x48,0x08,0xb1,
|
||||
0x88,0x2e,0xe1,0x93,0x5b,0x8c,0xc1,0x00,0x2b,0x90,0x04,0x50,0x18,0x92,0x01,0x8a,0xe0,0x21,0x3e,0xa9,
|
||||
0xd4,0x00,0x0b,0xa8,0x10,0x4a,0x01,0x15,0x30,0x00,0xa2,0x89,0x9d,0xd1,0x18,0x1c,0xc0,0x92,0x09,0x98,
|
||||
0x02,0x58,0x00,0x85,0x22,0x29,0x98,0xb0,0x19,0xf2,0x82,0x2e,0xac,0xd1,0x08,0x1a,0x11,0x33,0x14,0x04,
|
||||
0x10,0x99,0xb9,0x9a,0x3c,0xd2,0x96,0x29,0x8d,0xb9,0x99,0x88,0x42,0x70,0x11,0x82,0x82,0x89,0x8b,0xaa,
|
||||
0xb0,0x87,0x40,0x0d,0xc8,0x98,0x8a,0x18,0x40,0x32,0x14,0x02,0x00,0x9a,0xba,0xa9,0x98,0x37,0x3c,0xe9,
|
||||
0xc0,0x99,0x8a,0x38,0x41,0x14,0x13,0x11,0x09,0x0c,0x9a,0x88,0x10,0x7a,0xd4,0xa2,0x0d,0xab,0x88,0x00,
|
||||
0x24,0x51,0x10,0x01,0x09,0x98,0x08,0x19,0x90,0xa0,0x79,0xa9,0xf4,0xaa,0xaa,0x29,0x38,0x25,0x52,0x18,
|
||||
0x81,0xa1,0x81,0x39,0x1c,0xa8,0xf0,0x38,0xf2,0x00,0x8e,0xb1,0x98,0x11,0x61,0x28,0x92,0x11,0x19,0x29,
|
||||
0x0b,0xd2,0xa0,0xb8,0xb9,0x77,0x2d,0xc8,0x90,0x98,0x11,0x38,0x85,0x12,0x08,0x2b,0xaa,0xb4,0x01,0x1b,
|
||||
0xca,0xf2,0xa1,0x77,0x1b,0xd0,0x88,0x99,0x31,0x48,0x02,0x80,0xe1,0x28,0x1b,0x92,0x91,0x92,0x2f,0x8c,
|
||||
0x01,0x79,0xb7,0x10,0x8d,0x88,0x88,0x85,0x30,0x88,0x09,0xb9,0x83,0x3a,0x92,0x2a,0xf9,0x00,0x98,0x23,
|
||||
0x7d,0xe3,0xa2,0xaa,0x10,0x4a,0x83,0x12,0xa8,0x1a,0x9c,0x84,0x20,0xa0,0x98,0xaa,0x39,0x29,0x06,0x58,
|
||||
0xb7,0x4b,0x9e,0x00,0x80,0x15,0x19,0xa0,0x99,0xa1,0x50,0x19,0x00,0xaa,0x88,0x0a,0x04,0x31,0x3a,0x7f,
|
||||
0xf3,0x80,0x0b,0x38,0x88,0x87,0x08,0x89,0x1b,0xb2,0x23,0x08,0x2a,0xad,0x91,0x21,0x41,0x89,0xe1,0x79,
|
||||
0xe2,0x00,0xaa,0x21,0x19,0x15,0x89,0xa1,0x0c,0x80,0x48,0xa2,0x10,0xbb,0x88,0x88,0x17,0x29,0x98,0xca,
|
||||
0x57,0x0d,0xb0,0x09,0x82,0x60,0x80,0x80,0xc8,0x10,0x1a,0x12,0x98,0x91,0x0d,0x08,0x10,0x94,0x18,0x99,
|
||||
0x3c,0x07,0x3d,0xdb,0x08,0xa2,0x44,0x08,0x90,0xc9,0x82,0x5b,0x10,0x98,0xc1,0x09,0x19,0x38,0xa3,0x83,
|
||||
0xab,0x5c,0x07,0x2c,0xea,0x08,0x80,0x43,0x80,0x81,0xbb,0x81,0x19,0x05,0x19,0xc0,0x8a,0x80,0x69,0x91,
|
||||
0x01,0xa9,0x39,0x37,0x2f,0xdb,0x08,0x91,0x63,0x08,0x80,0xb9,0x01,0x3b,0x12,0xa8,0xd3,0x1b,0x89,0x11,
|
||||
0xa7,0x11,0x8b,0xb0,0x77,0x0a,0xc8,0x8a,0x81,0x50,0x01,0x00,0xb8,0x29,0x0a,0x12,0xa1,0x91,0x8f,0x90,
|
||||
0x10,0x23,0x2b,0xb8,0x9a,0x77,0xe2,0xa2,0x8d,0x18,0x28,0x05,0x18,0x99,0x8a,0xa1,0x31,0x81,0x89,0xe9,
|
||||
0x18,0x00,0x31,0xa0,0x08,0xac,0x70,0xa7,0x00,0xae,0x18,0x00,0x25,0x90,0x08,0xac,0x11,0x00,0x13,0x9b,
|
||||
0x99,0x0d,0x03,0x01,0x94,0x0c,0x89,0x39,0x77,0x1b,0xcb,0x8a,0x84,0x51,0x00,0x89,0xb8,0x28,0x01,0x20,
|
||||
0xe1,0x09,0x99,0x30,0xa3,0x02,0xba,0x4d,0x1a,0x57,0x8b,0xbb,0x8d,0x05,0x21,0x11,0x8c,0xa8,0x18,0x13,
|
||||
0x29,0xb8,0xac,0x01,0x69,0x01,0x89,0xb8,0x19,0x41,0x77,0x9b,0xaa,0x8b,0x15,0x31,0x82,0xac,0x90,0x28,
|
||||
0x33,0x99,0xe1,0x9a,0x30,0x39,0x94,0xc8,0x08,0x2b,0x61,0x27,0x8d,0xab,0x8b,0x07,0x11,0x01,0x9c,0x80,
|
||||
0x00,0x23,0x8a,0x99,0xbb,0x24,0x01,0x21,0xae,0x18,0x88,0x34,0x47,0x9e,0x99,0x8b,0x16,0x01,0x00,0xbb,
|
||||
0x01,0x82,0x52,0x9a,0x9a,0xc0,0x42,0x10,0x0a,0xf0,0x00,0x20,0x4a,0x07,0xbb,0x8a,0x8c,0x34,0x82,0x10,
|
||||
0xbc,0x28,0x93,0x33,0xc8,0x0d,0x98,0x21,0x03,0x8b,0xb8,0x1c,0x53,0x10,0x57,0xbc,0x9a,0xaa,0x36,0x01,
|
||||
0x18,0xca,0x18,0x02,0x40,0xb0,0x9b,0x88,0x49,0x04,0xa9,0x90,0x9c,0x42,0x11,0x77,0xba,0x8a,0xab,0x53,
|
||||
0x02,0x28,0xc9,0x09,0x03,0x40,0x81,0x9d,0xa0,0x08,0x43,0x99,0x90,0xda,0x31,0x28,0x77,0xb9,0x9a,0xba,
|
||||
0x42,0x13,0x20,0xc8,0x0b,0x12,0x31,0x86,0xab,0xa8,0x8a,0x34,0x90,0x18,0xbd,0x29,0x92,0x77,0xa2,0xac,
|
||||
0xd9,0x28,0x22,0x20,0xb2,0xab,0x30,0x59,0x33,0xc8,0xa8,0xbb,0x40,0x10,0x11,0xf0,0x89,0x88,0x71,0x87,
|
||||
0xa9,0xb9,0x0d,0x21,0x11,0x04,0xb9,0x08,0x08,0x63,0x81,0x88,0xc9,0x0b,0x11,0x30,0x83,0xbd,0x99,0x1b,
|
||||
0x77,0x91,0x9a,0xdc,0x08,0x02,0x42,0x81,0x9a,0xa0,0x38,0x44,0x28,0xa1,0xfa,0x88,0x19,0x30,0xa1,0xa0,
|
||||
0xe9,0x78,0x82,0x98,0xf8,0x8a,0x18,0x38,0x04,0xa1,0x92,0x0c,0x40,0x00,0x04,0xb1,0x1a,0x8c,0x29,0xb2,
|
||||
0x83,0x98,0x2f,0x07,0x98,0xb8,0x9f,0x09,0x88,0x15,0x00,0x18,0x9a,0x10,0x94,0x43,0x00,0x3a,0xc9,0x80,
|
||||
0xa2,0x38,0x1a,0x8e,0x61,0xa5,0xa0,0xbc,0x8e,0x88,0x81,0x23,0x89,0x82,0x2a,0x11,0x12,0x07,0x10,0x10,
|
||||
0x1a,0x81,0x80,0x02,0x0a,0xb9,0x77,0x92,0x8c,0xbf,0x98,0x98,0x22,0x19,0x29,0x9b,0x13,0x12,0x15,0x00,
|
||||
0x31,0x5a,0x11,0x94,0xa5,0x82,0x49,0x2c,0x57,0xab,0xa0,0x9d,0x02,0xa1,0x5a,0x1d,0x0a,0xb2,0xa3,0x84,
|
||||
0x2a,0x0a,0x2f,0x82,0x96,0x99,0x68,0x4b,0x08,0xc1,0xa1,0x02,0x79,0x99,0x38,0xd9,0x12,0xc8,0x10,0x1c,
|
||||
0x18,0xc0,0xb3,0x92,0x7a,0x3a,0x1a,0xb1,0x84,0x93,0x10,0x8c,0x7a,0xa0,0x08,0xa8,0x4a,0xa8,0x1a,0xf4,
|
||||
0x00,0x01,0x38,0x29,0x1c,0x82,0xb0,0x95,0xb3,0x20,0x1f,0x8a,0x92,0xd1,0x98,0x33,0x48,0x0e,0x18,0x21,
|
||||
0xa0,0xc8,0x92,0x58,0x08,0x9f,0x94,0x08,0x82,0x1f,0x30,0x0a,0xc4,0xa0,0x12,0x29,0x99,0xaa,0x95,0x12,
|
||||
0xc9,0x10,0x08,0x16,0x9e,0x22,0x1c,0xb3,0x0b,0x10,0x78,0x98,0x88,0x88,0x00,0x87,0x0c,0x81,0x19,0xc4,
|
||||
0x08,0x20,0x3c,0xa8,0xe2,0x93,0x11,0x3b,0x0c,0x82,0xa1,0xb2,0x2b,0x79,0x89,0xf2,0x82,0x18,0x88,0x11,
|
||||
0x1b,0x20,0x9e,0x94,0x09,0x01,0x2c,0x90,0x13,0xf0,0x48,0x80,0x29,0x0b,0x4b,0xd1,0x10,0xb0,0x7e,0xa0,
|
||||
0x80,0xd3,0x10,0x82,0x4c,0x89,0xa0,0xb3,0x92,0x08,0x38,0x8b,0xf5,0x01,0x92,0x19,0x8b,0x86,0x91,0x1b,
|
||||
0x38,0x6a,0x8a,0x99,0xa4,0x20,0x08,0x0f,0xa5,0x88,0xa3,0x1c,0x34,0x1f,0x08,0x09,0x92,0xc0,0x02,0x1a,
|
||||
0x80,0xb3,0x28,0x39,0x0f,0xa2,0x08,0x82,0x2c,0xa1,0x13,0xf0,0x40,0x9a,0x95,0x98,0x18,0x80,0x3b,0x3f,
|
||||
0x4b,0xb1,0x91,0x11,0x4f,0x19,0x99,0x92,0x98,0x13,0x2b,0x7c,0x1c,0x28,0x9a,0xb4,0x28,0x41,0x0f,0x81,
|
||||
0xb0,0x84,0x9a,0x52,0x0d,0x10,0x88,0x11,0xd8,0x20,0xb0,0x10,0xe3,0x28,0x92,0x4c,0x2b,0xa9,0x94,0x49,
|
||||
0x90,0x88,0xe4,0x28,0x88,0x18,0xb0,0x02,0x48,0x80,0x0f,0x12,0x19,0xa8,0x0e,0x80,0x15,0xca,0x41,0x08,
|
||||
0x3a,0xb9,0x2e,0xa5,0x09,0x80,0x08,0x24,0xcb,0x85,0x8c,0x22,0xb0,0x1a,0x84,0x2f,0x12,0x9d,0x92,0x18,
|
||||
0x86,0x0a,0xa8,0x4c,0x83,0x8a,0xc1,0x38,0x22,0x9b,0xca,0xa2,0x07,0x09,0x3b,0x88,0x13,0xf8,0x1b,0x95,
|
||||
0x01,0x80,0x99,0x88,0x7b,0x39,0xb8,0xb2,0xb5,0x5d,0x28,0x1b,0xc1,0xc4,0x02,0x2b,0x59,0xc9,0x82,0xc3,
|
||||
0x49,0x89,0x4b,0xe3,0x91,0x83,0x19,0x10,0x0e,0x81,0xa9,0x24,0xc8,0x28,0x98,0x5c,0x00,0xa8,0xa3,0x18,
|
||||
0x30,0x8b,0xba,0x3b,0x96,0x94,0x81,0x99,0xb9,0x05,0x68,0x8a,0x99,0xa8,0x63,0x01,0x2a,0xf9,0x92,0xa4,
|
||||
0x4b,0x1a,0x0b,0x97,0x90,0x88,0x3b,0x60,0xc1,0x90,0xa4,0x29,0x20,0x8e,0x03,0xc0,0x99,0x28,0x38,0x89,
|
||||
0x02,0x05,0x20,0x00,0xb8,0xab,0x00,0xef,0x11,0xb8,0x49,0x89,0x1c,0x15,0x00,0x12,0xa8,0x70,0xa1,0xbb,
|
||||
0xa1,0xac,0x59,0x00,0x18,0x84,0x89,0x30,0x98,0x11,0x84,0x1a,0x09,0xbc,0xa1,0x77,0x90,0x9d,0xa8,0xa8,
|
||||
0x42,0x20,0x10,0x92,0xa8,0x30,0x18,0x30,0x94,0xca,0x98,0x9c,0x2b,0x77,0xb0,0x8d,0x99,0x89,0x24,0x12,
|
||||
0x28,0x90,0xba,0x14,0x02,0x50,0x88,0xcb,0xa0,0xa8,0x7a,0x17,0xda,0x89,0x98,0x39,0x33,0xa2,0x01,0xa9,
|
||||
0x0c,0x33,0x83,0x14,0xa8,0x9f,0x88,0xa0,0x74,0x84,0xbc,0x8a,0x9a,0x48,0x24,0x80,0x80,0xb8,0x19,0x34,
|
||||
0x11,0x11,0xf9,0x9a,0x00,0x88,0x73,0x87,0xdb,0x98,0x88,0x30,0x32,0x88,0x98,0xb8,0x38,0x45,0x00,0x88,
|
||||
0xc9,0x9a,0x30,0x18,0x71,0x87,0xcc,0x89,0x08,0x20,0x24,0xa8,0x88,0x09,0x39,0x16,0xa2,0x88,0x9b,0x0c,
|
||||
0x21,0x92,0x70,0x87,0xcd,0x88,0x01,0x28,0x22,0xa8,0x99,0x81,0x20,0x44,0x90,0xa9,0xa9,0x89,0x32,0x82,
|
||||
0x7a,0x07,0xce,0x09,0x01,0x28,0x22,0xc0,0x89,0x20,0x28,0x33,0xc2,0xca,0x08,0x19,0x30,0xa2,0x3c,0x67,
|
||||
0xeb,0x8b,0x12,0x80,0x22,0xa2,0xbb,0x21,0x22,0x32,0x94,0xbc,0x8b,0x01,0x13,0x92,0xbc,0x77,0xd1,0x9e,
|
||||
0x11,0x81,0x28,0x01,0xaa,0x19,0x23,0x11,0x01,0xca,0x9b,0x38,0x22,0x80,0xeb,0x7a,0x17,0xec,0x09,0x12,
|
||||
0x88,0x21,0x90,0xab,0x31,0x23,0x80,0x89,0xab,0x8b,0x15,0x84,0x8a,0x8c,0x71,0x97,0xcd,0x10,0x02,0x88,
|
||||
0x11,0xa0,0xaa,0x52,0x21,0x0a,0x8a,0xb0,0x90,0x43,0x00,0xad,0xa9,0x77,0xb1,0x9e,0x10,0x82,0x08,0x11,
|
||||
0xa8,0x0c,0x41,0x82,0xa8,0x08,0x09,0x8a,0x14,0xa3,0xac,0x2b,0x77,0xb0,0x9e,0x20,0x01,0x09,0x11,0xa0,
|
||||
0x8c,0x41,0x03,0xa9,0x89,0x80,0x99,0x42,0x93,0xcc,0x0a,0x75,0x92,0xbf,0x28,0x12,0x89,0x20,0x91,0xcb,
|
||||
0x40,0x23,0xa8,0x9b,0x82,0xb0,0x20,0x25,0xca,0x9c,0x21,0x67,0xc0,0xac,0x20,0x02,0x90,0x11,0x98,0x9c,
|
||||
0x41,0x04,0xb0,0x99,0x01,0x09,0x39,0x13,0xfa,0x9a,0x41,0x46,0xb8,0xbf,0x20,0x12,0x88,0x10,0x88,0x9c,
|
||||
0x40,0x04,0xa0,0x9a,0x10,0x08,0x08,0x13,0xd9,0x9c,0x21,0x76,0x91,0xbe,0x19,0x13,0x81,0x09,0x00,0xb9,
|
||||
0x29,0x36,0x91,0xbb,0x08,0x02,0x88,0x30,0xa0,0xce,0x18,0x53,0x27,0xf9,0x9b,0x30,0x12,0x98,0x08,0x90,
|
||||
0xa9,0x61,0x23,0xb9,0x9c,0x11,0x11,0x89,0x10,0xc8,0xbb,0x50,0x52,0x17,0xf8,0xab,0x30,0x23,0xa8,0x09,
|
||||
0x80,0x98,0x40,0x34,0xb8,0xad,0x20,0x83,0xa0,0x08,0x90,0xac,0x08,0x24,0x77,0xa1,0xbf,0x18,0x23,0x91,
|
||||
0x8a,0x18,0x88,0x09,0x35,0x92,0xbc,0x1a,0x33,0xa1,0xa9,0x10,0xca,0x8c,0x73,0x21,0x16,0xf8,0xad,0x20,
|
||||
0x23,0xa0,0x8a,0x00,0x80,0x28,0x25,0xb1,0xbc,0x28,0x24,0x98,0x8a,0x08,0xaa,0x1a,0x34,0xb2,0x70,0x27,
|
||||
0xee,0x89,0x32,0x82,0x9a,0x19,0x01,0x89,0x41,0x13,0xca,0x8c,0x31,0x83,0xb9,0x09,0x80,0xbb,0x38,0x16,
|
||||
0xb8,0x77,0xa1,0xbf,0x29,0x33,0x90,0x9a,0x20,0x90,0x09,0x44,0x82,0xbc,0x2a,0x43,0xa0,0x9a,0x10,0xa9,
|
||||
0x8c,0x41,0x82,0xdb,0x71,0x07,0xcc,0x0a,0x33,0x81,0x8b,0x28,0x91,0xaa,0x73,0x12,0xba,0x8b,0x32,0x92,
|
||||
0x9a,0x38,0xa9,0xaf,0x11,0x04,0xb8,0x3b,0x77,0xd1,0xac,0x30,0x13,0xa8,0x09,0x01,0xa9,0x38,0x27,0xa0,
|
||||
0xbb,0x20,0x23,0x99,0x1a,0x80,0xbd,0x1a,0x53,0x90,0xbb,0x69,0x77,0xc8,0x9c,0x30,0x02,0x98,0x18,0x81,
|
||||
0xaa,0x48,0x34,0xb0,0xbb,0x30,0x11,0xa9,0x01,0xc3,0xcc,0x2a,0x32,0xa8,0xb9,0x83,0x77,0x87,0xcc,0x1a,
|
||||
0x22,0x81,0x89,0x01,0xa8,0x0a,0x35,0x84,0xba,0x0a,0x12,0xa1,0x00,0x21,0xbe,0x8c,0x22,0x83,0xba,0x09,
|
||||
0x00,0x78,0x77,0xd9,0x8b,0x31,0x02,0x99,0x01,0xa0,0x8b,0x71,0x22,0xc8,0xa9,0x11,0x01,0x09,0x20,0xc9,
|
||||
0xcb,0x11,0x04,0x98,0x8a,0x00,0x98,0x77,0x97,0xad,0x18,0x12,0x90,0x08,0x01,0xb9,0x19,0x36,0x91,0xab,
|
||||
0x18,0x82,0x99,0x21,0x92,0xce,0x1a,0x32,0x88,0x9b,0x00,0xb1,0x39,0x77,0x97,0xaf,0x10,0x12,0x88,0x18,
|
||||
0x80,0xab,0x48,0x34,0xa0,0xab,0x20,0x80,0x09,0x42,0xb0,0xaf,0x08,0x11,0x01,0x80,0x99,0xab,0x38,0x74,
|
||||
0x67,0xd9,0x9b,0x31,0x01,0x88,0x11,0xc8,0x9a,0x62,0x12,0xa9,0x89,0x81,0x98,0x31,0x13,0xfb,0x9a,0x11,
|
||||
0x81,0x19,0x29,0xcb,0xaa,0x34,0x73,0x47,0xf9,0x8b,0x21,0x81,0x18,0x10,0xb9,0x8c,0x62,0x02,0x99,0x88,
|
||||
0x90,0x98,0x32,0x04,0xbc,0x9a,0x11,0x88,0x28,0x20,0xbe,0x99,0x05,0x92,0x76,0x94,0xbe,0x08,0x03,0x08,
|
||||
0x30,0x98,0xdb,0x20,0x24,0x80,0x1a,0x98,0xd8,0x11,0x23,0xa9,0x9c,0x88,0xa8,0x30,0x12,0xcb,0xaa,0x02,
|
||||
0x13,0x12,0x77,0x27,0xcf,0x18,0x81,0x00,0x21,0x98,0x9c,0x20,0x23,0x81,0x08,0xaa,0x9b,0x42,0x03,0xa9,
|
||||
0xaa,0xac,0x0a,0x23,0x92,0xab,0x0f,0x19,0x20,0x05,0x72,0x77,0xdb,0x09,0x81,0x18,0x31,0xa0,0x9c,0x10,
|
||||
0x12,0x31,0x02,0xbb,0x9b,0x22,0x31,0x39,0xcc,0xfa,0x90,0x01,0x38,0x09,0xbc,0xa0,0x83,0x42,0x11,0x77,
|
||||
0x87,0xad,0x08,0x90,0x20,0x14,0xaa,0x89,0x01,0x11,0x34,0x88,0x9c,0x88,0x92,0x12,0x10,0x8f,0x8a,0x88,
|
||||
0x80,0x92,0xa0,0x8a,0x09,0x82,0x87,0xa3,0x77,0x87,0xad,0x80,0xa0,0x31,0x03,0x9b,0x09,0xb1,0x42,0x25,
|
||||
0x0a,0x0a,0xa8,0x80,0x05,0x98,0x98,0xaa,0x8a,0x11,0x80,0x0a,0xbc,0x1c,0x43,0x01,0x85,0x73,0x67,0xdb,
|
||||
0x88,0x99,0x38,0x23,0xa9,0x81,0xc8,0x40,0x33,0x09,0x80,0xd1,0x8a,0x13,0x3a,0x3a,0xfb,0xb0,0x92,0x08,
|
||||
0x38,0x8b,0x8b,0xc3,0xa3,0x25,0x29,0x77,0xa7,0x0c,0xa9,0x8a,0x24,0x91,0x10,0x88,0x1d,0x22,0x91,0x12,
|
||||
0xb1,0x0c,0x21,0x9b,0x12,0xf1,0x8a,0x81,0x8a,0x48,0xb8,0xa0,0x96,0x80,0x30,0x99,0x78,0x77,0x99,0x98,
|
||||
0xac,0x19,0x80,0x29,0x11,0x89,0x43,0x03,0x42,0x12,0x8a,0x20,0xd8,0x88,0xb0,0x9d,0x89,0xbb,0x09,0xc0,
|
||||
0x80,0x14,0x49,0x78,0x18,0x20,0x77,0x92,0x09,0xdb,0xab,0x90,0x9a,0x10,0x80,0x40,0x24,0x31,0x25,0x02,
|
||||
0x22,0x91,0xa9,0xb8,0xaf,0x9b,0xdb,0xa9,0xa0,0x09,0x30,0x31,0x42,0x24,0x33,0x75,0x17,0x08,0xa0,0xcb,
|
||||
0x9a,0xbb,0x9b,0xa8,0x98,0x43,0x31,0x73,0x23,0x32,0x15,0x01,0x21,0x99,0x9b,0xcb,0xcd,0xb8,0xba,0x8b,
|
||||
0x8b,0x1b,0x11,0x03,0x47,0x77,0x00,0x10,0x99,0xaa,0xc0,0xaa,0x89,0x9a,0x29,0x81,0x22,0x17,0x22,0x52,
|
||||
0x20,0x20,0x82,0xa1,0x81,0xac,0x9b,0xbd,0xcb,0xb9,0xbb,0x89,0x8b,0x81,0x77,0x17,0x18,0x01,0xbb,0x89,
|
||||
0xcc,0x8a,0xa8,0x1a,0x21,0x20,0x36,0x13,0x43,0x14,0x20,0x21,0x98,0x90,0xe9,0x9a,0xcb,0x9c,0xaa,0xbb,
|
||||
0x99,0xb8,0x21,0x79,0x77,0x11,0x01,0xba,0x8a,0xcc,0xaa,0x98,0x0a,0x32,0x20,0x27,0x13,0x52,0x21,0x10,
|
||||
0x01,0x98,0x98,0xcb,0x9c,0xca,0xba,0xb9,0x9b,0x0a,0x0b,0x10,0x45,0x77,0x13,0x21,0xca,0xab,0xea,0x9b,
|
||||
0x99,0x9a,0x22,0x11,0x45,0x23,0x52,0x22,0x20,0x02,0xa0,0x90,0xdb,0xab,0xdb,0xab,0xb9,0xba,0x80,0x98,
|
||||
0x58,0x20,0x77,0x05,0x11,0xb9,0xaa,0xea,0x9b,0x99,0x8a,0x21,0x11,0x45,0x23,0x52,0x12,0x11,0x02,0x98,
|
||||
0x88,0xbb,0xad,0xda,0xaa,0xb9,0x8c,0x89,0x9a,0x01,0x70,0x77,0x18,0x01,0xaa,0x99,0xdb,0x9a,0x99,0x0a,
|
||||
0x02,0x21,0x37,0x21,0x43,0x02,0x22,0x82,0x09,0x98,0xad,0xaa,0x9c,0xba,0xba,0xbb,0xae,0xa9,0xb9,0x77,
|
||||
0x03,0x21,0xb1,0xab,0xe9,0x9d,0x98,0x9a,0x11,0x02,0x72,0x12,0x32,0x23,0x11,0x13,0x90,0x18,0xbc,0xac,
|
||||
0xda,0xbb,0xa9,0x9d,0x99,0xa9,0x10,0x79,0x57,0x10,0x01,0xba,0x9a,0xec,0x99,0xa9,0x09,0x01,0x20,0x35,
|
||||
0x22,0x35,0x12,0x32,0x82,0x00,0xa0,0xac,0xb9,0xae,0x9a,0xcb,0x09,0xa9,0x09,0x00,0x77,0x13,0x21,0xca,
|
||||
0xaa,0xfb,0x9b,0x9a,0x9b,0x00,0x11,0x54,0x22,0x53,0x13,0x32,0x13,0x00,0x02,0x9b,0xa9,0xfb,0x9a,0xbb,
|
||||
0x9d,0x1a,0x80,0x80,0x08,0x80,0x08,0x80,0x08,0x80,0x08,0x80,0x08,0x80,0x08,0x08,0x08,0x08,0x80,0x80,
|
||||
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,
|
||||
};
|
||||
static constexpr VoiceClip gpsOnClip = {
|
||||
gpsOnData, sizeof(gpsOnData), 9683, 8000
|
||||
};
|
||||
static const uint8_t gpsOffData[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,
|
||||
0x7f,0xf7,0xf7,0x61,0x5c,0x8b,0xd1,0x04,0x4a,0x8c,0xb3,0x83,0x90,0x98,0x91,0x22,0x2d,0x89,0x28,0xd1,
|
||||
0xa3,0x20,0x0a,0x80,0xf1,0xb7,0x01,0x5d,0x1a,0x88,0x91,0x18,0x2a,0xa0,0xb5,0x81,0x38,0x2c,0x88,0x2b,
|
||||
0x5a,0xb9,0xa7,0xa1,0xb4,0xc3,0x51,0x1d,0x08,0x90,0x20,0x3c,0x1b,0xf3,0xa3,0x81,0x28,0x1b,0x98,0xb4,
|
||||
0x82,0x6c,0x8a,0xc3,0xc4,0x11,0x09,0x00,0x0a,0xb1,0xa5,0x20,0x2c,0x39,0x4f,0x8a,0xa2,0x01,0x5b,0x0a,
|
||||
0xc1,0xb6,0x82,0x4a,0x8a,0xb2,0x02,0x5c,0x1b,0xa1,0xa2,0x01,0x3a,0x2a,0x3b,0x99,0xf7,0xa3,0x30,0x2d,
|
||||
0x19,0x29,0x2c,0xc0,0xb5,0x21,0x3c,0x2b,0xc0,0xb4,0xb4,0x11,0x2a,0x1a,0x98,0x82,0x3a,0x89,0x10,0xb9,
|
||||
0xb7,0x82,0x5a,0x2b,0xe0,0xc6,0x82,0x49,0x2c,0x89,0xc3,0x82,0x29,0x4b,0x8a,0xd4,0xa3,0x20,0x4d,0x0a,
|
||||
0xc2,0x82,0x29,0x2b,0xb0,0xb5,0x02,0x4b,0x3b,0x8a,0xd4,0xb4,0x01,0x29,0x4b,0x2b,0xd0,0xb6,0x82,0x39,
|
||||
0x2c,0x89,0xb2,0xa3,0x10,0x1a,0x90,0xa2,0x50,0x2e,0xe1,0xb4,0x02,0x5c,0x2b,0x89,0xa2,0x01,0x19,0x09,
|
||||
0xc2,0x11,0x3b,0x4c,0xa9,0xb5,0x11,0x5b,0x1b,0xc1,0x83,0x5b,0x0a,0xc2,0x82,0x39,0x2c,0x88,0x29,0x89,
|
||||
0x93,0x4d,0x99,0xe6,0xb5,0x82,0x5b,0x2b,0x98,0xc3,0x82,0x49,0x3d,0x99,0xc4,0x82,0x39,0x3d,0x99,0xc3,
|
||||
0x93,0x39,0x2c,0x09,0xb1,0xa4,0x10,0x3b,0x89,0xb2,0x12,0x3d,0xc8,0xb5,0x21,0x4f,0x2b,0xa0,0xb3,0x92,
|
||||
0x18,0x19,0x4a,0x3c,0x0a,0x00,0x3a,0x0a,0xf5,0xc5,0x21,0x3d,0x0a,0xa1,0xa3,0x80,0xb1,0x03,0x6e,0x2c,
|
||||
0x98,0xb3,0x92,0x00,0x5b,0x1a,0x88,0x00,0x19,0x98,0xc6,0x21,0x4f,0x0a,0xa0,0xb4,0x82,0x08,0x19,0x08,
|
||||
0x4a,0x1a,0x29,0xb8,0xb4,0xc5,0x21,0x3c,0x4b,0x9a,0xc5,0x82,0x39,0x3d,0x0a,0xb1,0xa4,0x81,0x18,0x2a,
|
||||
0xa8,0xa4,0x28,0xb0,0x31,0x2e,0xa0,0xc3,0xb3,0x70,0x4f,0x0a,0xc1,0xa3,0x20,0x4d,0x1a,0xb0,0xa5,0x10,
|
||||
0x4b,0x0a,0xa1,0xc3,0x82,0x19,0x19,0xa0,0x11,0x3b,0x1b,0xf5,0xa3,0x10,0x4c,0x0a,0x80,0x30,0x9a,0xb7,
|
||||
0x11,0x2c,0x8a,0xb0,0xb2,0x21,0x6c,0x19,0x91,0x93,0x02,0x29,0x2b,0x0b,0x8b,0xf8,0x24,0x3f,0xc0,0xa3,
|
||||
0x88,0x8a,0x1a,0x9a,0xa4,0x13,0x32,0x34,0x50,0x18,0x98,0xd1,0xb0,0x99,0x1f,0xb3,0x78,0x2b,0xd1,0x00,
|
||||
0x0c,0xa8,0x00,0x18,0x12,0x52,0x12,0x32,0x39,0xb9,0xd0,0xaa,0xcb,0x2a,0xf3,0x04,0x5c,0x9a,0xb2,0x19,
|
||||
0x9b,0x91,0x30,0x41,0x62,0x21,0x83,0x11,0x1c,0xbb,0xe8,0x99,0x59,0x2d,0xc1,0x83,0x2c,0xaa,0xb1,0x08,
|
||||
0x00,0x42,0x51,0x03,0x15,0x10,0x89,0xa9,0xca,0xba,0x0c,0xf2,0x12,0x4d,0xb8,0xb4,0x39,0x0c,0x90,0x11,
|
||||
0x20,0x14,0x42,0x20,0x91,0xb1,0xc9,0xca,0xab,0x6b,0x1d,0xe2,0x83,0x3b,0x9b,0xb2,0x18,0x90,0x06,0x60,
|
||||
0x10,0x83,0x11,0x0a,0xb8,0x9b,0x9e,0x1a,0xd9,0xb7,0x30,0x1d,0xc0,0x92,0x29,0x09,0x11,0x31,0x13,0x15,
|
||||
0x30,0x1a,0xb9,0xf9,0xb8,0x8a,0xe2,0x12,0x3e,0xc9,0xb4,0x39,0x1c,0x90,0x02,0x12,0x14,0x42,0x28,0x98,
|
||||
0xc1,0xa9,0x9c,0x0c,0xf2,0x83,0x4c,0xa9,0xc3,0x18,0x8a,0x81,0x40,0x38,0x13,0x24,0x01,0xa2,0x98,0x9e,
|
||||
0xca,0x99,0xf3,0x83,0x4d,0xa9,0xd3,0x10,0x1b,0xa0,0x84,0x31,0x21,0x42,0x28,0xb0,0xd3,0x1a,0x0f,0x0a,
|
||||
0xd1,0xb5,0x20,0x1d,0xa8,0x92,0x19,0x08,0x12,0x60,0x01,0x94,0x12,0x3c,0xab,0xf2,0x80,0x4a,0x1c,0xc1,
|
||||
0xa4,0x39,0x0c,0xa0,0x81,0x18,0x01,0x33,0x70,0x08,0xb3,0x82,0x1c,0x8c,0xc8,0xb3,0x58,0x1c,0xb0,0x81,
|
||||
0x1d,0xb8,0x93,0x69,0x18,0x85,0x22,0x28,0xa0,0xc2,0x89,0x9c,0xa9,0xc5,0x12,0x3d,0x9a,0xd2,0x08,0x8a,
|
||||
0xa2,0x32,0x40,0x14,0x33,0x38,0xb0,0xe2,0x0a,0x8f,0x00,0x3b,0xf0,0xb4,0x38,0x1e,0xb0,0xa3,0x20,0x29,
|
||||
0x12,0x41,0x18,0xb3,0x92,0x2d,0x8d,0x99,0xd3,0x83,0x4c,0x8b,0xb0,0x19,0x8c,0xb2,0x24,0x79,0x10,0x03,
|
||||
0x82,0x81,0x09,0x0e,0xab,0x01,0x3c,0xf0,0xa4,0x4a,0x0d,0xb0,0x82,0x18,0x81,0x14,0x50,0x18,0x91,0xa2,
|
||||
0x09,0x0d,0x8b,0xf4,0x93,0x6b,0x0b,0xc1,0x81,0x1a,0x98,0x12,0x48,0x01,0x85,0x12,0x08,0x98,0x0a,0x0f,
|
||||
0x88,0x09,0xe1,0xb3,0x4a,0x0d,0xa8,0x81,0x28,0x01,0x15,0x60,0x18,0xa2,0x82,0x0b,0xca,0x88,0xb0,0x94,
|
||||
0x5d,0x0c,0xc0,0xa1,0x88,0x08,0x30,0x30,0x86,0x86,0x21,0x19,0x89,0xa9,0xd9,0x82,0x4e,0x9a,0xc3,0x00,
|
||||
0x1c,0x99,0x00,0x4a,0x00,0x85,0x32,0x38,0x81,0x92,0x8a,0xad,0xc9,0xa3,0x7b,0x1c,0xe2,0x81,0x2b,0x9b,
|
||||
0xc3,0x31,0x5a,0x01,0x04,0x21,0x18,0x98,0x99,0xbb,0x9b,0xf3,0x02,0x5f,0x8b,0xe2,0x81,0x2a,0x0a,0x81,
|
||||
0x12,0x12,0x24,0x40,0x29,0x99,0xf1,0xa0,0x1a,0xa8,0x93,0x5d,0x8b,0xe2,0x00,0x2b,0x8a,0x93,0x04,0x32,
|
||||
0x61,0x28,0x91,0xb2,0xa0,0x0d,0x9c,0xc3,0x58,0x2d,0xc0,0x92,0x2b,0x9b,0xc3,0x31,0x5a,0x01,0x14,0x31,
|
||||
0x08,0xa1,0x99,0x9d,0xba,0x3b,0xbb,0xc7,0x33,0x2f,0xaa,0xd3,0x00,0x2a,0x08,0x03,0x43,0x31,0x12,0x10,
|
||||
0x9a,0xf9,0xb8,0x8b,0x4c,0x1b,0xe5,0x83,0x4c,0x8b,0xc1,0x01,0x2a,0x00,0x31,0x30,0x85,0x13,0x4b,0xaa,
|
||||
0xd1,0x99,0x8b,0x3a,0x2c,0xe5,0x83,0x5b,0x9b,0xd3,0x00,0x1a,0x81,0x13,0x31,0x04,0x32,0x1a,0xe0,0xa0,
|
||||
0x0d,0x9b,0x08,0xd2,0x85,0x6a,0x8a,0xd2,0x00,0x1b,0x98,0x82,0x22,0x41,0x41,0x11,0x92,0x88,0x8c,0xbc,
|
||||
0xb9,0xaa,0x42,0x5d,0xb1,0x84,0x2b,0xbb,0xe1,0x08,0x2a,0x10,0x15,0x43,0x31,0x11,0xa1,0xa8,0xad,0xac,
|
||||
0xba,0x9a,0x87,0x58,0x88,0xa2,0x09,0x8d,0xba,0xa0,0x48,0x48,0x23,0x17,0x31,0x00,0xa1,0xa8,0x9d,0xbb,
|
||||
0xca,0x09,0x42,0x38,0x85,0x91,0x0a,0xaf,0xc8,0x89,0x19,0x11,0x25,0x34,0x42,0x11,0x81,0x98,0xac,0xdb,
|
||||
0xba,0x9a,0x39,0x12,0x25,0x21,0x80,0xd8,0xca,0xbb,0x8c,0xa8,0xa8,0x72,0x43,0x24,0x32,0x21,0x00,0x99,
|
||||
0xcb,0xbc,0xab,0xa9,0x00,0x08,0x80,0xa1,0xaa,0xbd,0xdb,0xa9,0x0a,0x30,0x44,0x35,0x34,0x24,0x23,0x12,
|
||||
0x81,0xa8,0xbb,0x09,0x8b,0xb9,0xfb,0xbd,0xbd,0xdb,0xaa,0x9b,0x89,0x11,0x44,0x53,0x33,0x24,0x23,0x12,
|
||||
0x00,0xa8,0xba,0x9d,0x91,0x18,0x80,0xb8,0xdc,0xbc,0xcd,0xba,0xba,0x9a,0x18,0x41,0x44,0x43,0x24,0x33,
|
||||
0x32,0x21,0x80,0xa8,0x1b,0xc9,0xa8,0xdb,0xcb,0xad,0xdb,0xaa,0xab,0x9a,0x88,0x30,0x52,0x34,0x34,0x34,
|
||||
0x32,0x23,0x22,0x01,0xa1,0x35,0x1b,0xa8,0xcc,0xbd,0xbd,0xdb,0xaa,0xab,0x9a,0x89,0x11,0x35,0x63,0x42,
|
||||
0x32,0x32,0x32,0x12,0x01,0xb0,0x54,0x8d,0xa8,0xdb,0xbb,0xbc,0xac,0xaa,0x99,0x00,0x33,0x45,0x53,0x32,
|
||||
0x23,0x14,0x02,0x81,0xa8,0xba,0xcd,0x21,0x9f,0xa8,0xc9,0xa9,0xaa,0xa9,0x10,0x41,0x51,0x43,0x23,0x24,
|
||||
0x23,0x12,0x00,0xa9,0xcc,0xda,0xba,0xda,0x32,0x0e,0x08,0x99,0xa9,0x80,0x88,0x41,0x32,0x34,0x43,0x33,
|
||||
0x32,0x93,0xb1,0xda,0xdb,0xca,0xaa,0xdb,0xb8,0x67,0x0a,0x00,0x08,0xba,0x29,0xba,0xb5,0x87,0x08,0x01,
|
||||
0x08,0x11,0xa5,0x21,0x1e,0xa8,0xa0,0xa2,0x1b,0x31,0x88,0xf1,0x38,0xc0,0x12,0x91,0x70,0x80,0x98,0x19,
|
||||
0x8b,0xa2,0x5c,0xc0,0x80,0x21,0x18,0x79,0xa8,0x97,0xa2,0x19,0x9b,0xa9,0x0a,0x8e,0x7b,0xa1,0x81,0x20,
|
||||
0x19,0x88,0x07,0x88,0x1a,0x14,0x3a,0x59,0xc8,0x90,0x82,0x9d,0x00,0x89,0xe1,0x13,0x28,0x3d,0x89,0x80,
|
||||
0x11,0x09,0xf9,0x89,0x29,0xe4,0x08,0x83,0x49,0x5a,0x90,0x18,0xb1,0x29,0x4b,0x90,0x11,0xb3,0x1f,0x1a,
|
||||
0x99,0x18,0xb9,0xb2,0x87,0x41,0x69,0x00,0x19,0x0b,0xcb,0xaa,0xb7,0x11,0x00,0x90,0x9e,0x80,0x42,0x8d,
|
||||
0x30,0xa0,0xa6,0x04,0x0a,0x00,0x99,0x01,0xd3,0x21,0x1f,0x89,0xa0,0x08,0x18,0x02,0x02,0x51,0x95,0x22,
|
||||
0x89,0x8f,0xc1,0x90,0x19,0x91,0xa8,0x5b,0x3d,0x98,0x02,0xa2,0x1f,0x9a,0x96,0x02,0x2a,0x11,0x42,0x5a,
|
||||
0x08,0xb1,0x00,0xa8,0x9f,0xc2,0xa9,0xa0,0x8e,0x21,0x6b,0x10,0x83,0x1a,0x11,0xb0,0x82,0xd1,0x90,0x30,
|
||||
0x4c,0x09,0xa3,0x9a,0xc8,0xf1,0xb8,0x07,0x1b,0x89,0xb3,0x91,0x70,0x09,0x81,0x6a,0xb2,0x2d,0x14,0xb9,
|
||||
0x33,0xf9,0x38,0xa9,0x9a,0x10,0x1c,0x93,0x7b,0xb1,0x18,0x04,0xf0,0x7f,0xb1,0x3a,0x08,0x9a,0x07,0x0b,
|
||||
0xa6,0x0a,0x12,0x0a,0x80,0xf3,0x21,0x1a,0x2f,0xb0,0x01,0x93,0x1a,0x0a,0x8a,0x17,0x5d,0xa0,0xaa,0x07,
|
||||
0x3d,0x88,0x00,0x88,0x2a,0xc0,0x95,0x29,0x18,0x0f,0xa4,0x90,0x02,0x48,0x9d,0x05,0x0d,0xa4,0x3b,0xb1,
|
||||
0x38,0xc1,0x01,0x92,0x5b,0xa9,0x95,0x3a,0x08,0x1e,0xc4,0x28,0x88,0x08,0xb4,0x80,0x58,0x8d,0x94,0x0a,
|
||||
0x93,0x5d,0xc0,0x21,0xb8,0x22,0x0b,0xb1,0x41,0xac,0x14,0x1d,0x92,0x98,0x83,0x4e,0xa8,0x11,0xb8,0x22,
|
||||
0x8c,0x01,0x09,0x28,0xc2,0x7a,0xe8,0x84,0x88,0x39,0xb8,0x11,0xf1,0x22,0x2e,0x90,0x08,0xb2,0x30,0xaa,
|
||||
0x12,0x1d,0xc3,0x11,0xa9,0xa7,0x49,0xaa,0xa6,0x38,0x8a,0x10,0xa9,0xa5,0x49,0x0a,0x81,0x2a,0xe1,0x94,
|
||||
0x39,0x0a,0x29,0xd8,0xa6,0x10,0x1a,0x90,0x28,0xa8,0x93,0x88,0x90,0x20,0x9c,0xc7,0x21,0x89,0x30,0x1d,
|
||||
0x98,0xc5,0x11,0x0a,0x38,0x2d,0xd1,0xa4,0x28,0x1a,0x19,0xd2,0x02,0x4c,0x0a,0xa2,0x18,0xc0,0xb5,0x02,
|
||||
0x5b,0x2b,0x99,0xd6,0x93,0x28,0x2b,0x19,0x1a,0xe2,0xb4,0x82,0x4a,0x1b,0xd1,0xb4,0x12,0x4c,0x0a,0xa0,
|
||||
0xb4,0x02,0x5b,0x2b,0x09,0xb0,0xb7,0xa3,0x38,0x3d,0x0a,0x90,0x91,0xb3,0x40,0x2c,0x89,0xa1,0x02,0xa8,
|
||||
0x31,0x3c,0xc8,0xb7,0x81,0x00,0x4c,0x8a,0xa2,0x20,0xb8,0x44,0x3f,0xb9,0xb6,0x01,0x2a,0x88,0x6a,0x1b,
|
||||
0xb1,0xc6,0x93,0x38,0x3e,0x0a,0xb1,0xa3,0x18,0x18,0x19,0x4a,0x8a,0x21,0x1e,0xe2,0xb5,0x20,0x3b,0x0a,
|
||||
0x00,0xc0,0xa5,0x01,0x6b,0x2c,0x19,0x88,0xc2,0xb3,0x31,0x1f,0x80,0x08,0x80,0xb1,0xb4,0x42,0x3e,0x89,
|
||||
0x90,0x88,0xc1,0xa3,0x48,0x3c,0x09,0x91,0x01,0x90,0x92,0x38,0x3c,0x9a,0x17,0x7a,0x0a,0xc0,0x80,0x0c,
|
||||
0xa9,0xa2,0x11,0x20,0x22,0x51,0x10,0xa2,0xb3,0x80,0x3c,0xb7,0x51,0x2f,0xa9,0x91,0x8a,0xc8,0xb3,0x40,
|
||||
0x4b,0x00,0x03,0x11,0xa2,0xa4,0x18,0x4f,0xa8,0xa5,0x18,0x8b,0xd8,0x90,0x0a,0x89,0x02,0x51,0x30,0x03,
|
||||
0x14,0x38,0x1b,0xab,0x7a,0xb8,0xc7,0x82,0x2d,0x9b,0xb0,0x08,0x09,0x02,0x53,0x58,0x01,0x83,0x10,0x8a,
|
||||
0xd8,0x22,0x3f,0xb9,0xc5,0x08,0x8b,0xb8,0x00,0x4a,0x00,0x05,0x41,0x28,0x81,0x81,0x1a,0x0c,0xe5,0x93,
|
||||
0x5b,0x8c,0xa0,0x88,0x8a,0xc2,0x13,0x7a,0x18,0x82,0x12,0x19,0x98,0x98,0x48,0x3e,0xc9,0xc3,0x09,0x8c,
|
||||
0xb8,0x10,0x4a,0x81,0x87,0x22,0x38,0x80,0x91,0x8a,0x0c,0xf3,0x83,0x3d,0x9b,0xf2,0x80,0x2b,0x99,0x83,
|
||||
0x50,0x10,0x04,0x21,0x29,0xb8,0xd1,0x20,0x2e,0xc8,0xc3,0x19,0x0d,0xa8,0x00,0x39,0x00,0x06,0x31,0x38,
|
||||
0x91,0x92,0x0a,0x1e,0xf3,0xa3,0x39,0x0e,0xb8,0x09,0x0b,0xb1,0x85,0x41,0x30,0x22,0x40,0x09,0xe1,0xb1,
|
||||
0x58,0x2e,0xa8,0xc3,0x18,0x0c,0xa8,0x28,0x4c,0x88,0x95,0x22,0x39,0x80,0x81,0x1a,0x8c,0xf5,0xa3,0x39,
|
||||
0x0d,0xa8,0x80,0x1a,0xb0,0x96,0x31,0x39,0x02,0x03,0x38,0x0c,0xb9,0x21,0x3f,0xcb,0xd6,0x00,0x1b,0xa9,
|
||||
0x92,0x59,0x3a,0x92,0x86,0x02,0x00,0x00,0x1b,0x1c,0xf1,0xb3,0x38,0x1e,0xa9,0x90,0x1a,0x89,0x93,0x14,
|
||||
0x32,0x24,0x32,0x39,0xb8,0xf2,0xd4,0x20,0x2f,0x9a,0xb1,0x08,0x8b,0xb2,0x13,0x50,0x11,0x05,0x21,0x08,
|
||||
0xb1,0x98,0x7a,0x3e,0xaa,0xd4,0x91,0x1a,0x8a,0x88,0x39,0x10,0x96,0x85,0x21,0x18,0x80,0x09,0x5c,0x0b,
|
||||
0xf3,0x91,0x1a,0x8c,0x98,0x19,0x19,0xa3,0x07,0x31,0x48,0x18,0x90,0xb1,0x88,0xf2,0xa3,0x5c,0x0d,0xc0,
|
||||
0xa2,0x08,0x09,0x92,0x32,0x58,0x01,0x83,0x20,0x1c,0xd8,0xc5,0x11,0x3d,0x9b,0xb1,0x08,0x0b,0xc1,0x84,
|
||||
0x40,0x38,0x11,0x02,0x92,0xc2,0xa1,0x91,0x6c,0x1e,0xa9,0xc1,0x88,0x9a,0xb2,0x32,0x7a,0x01,0x95,0x13,
|
||||
0x29,0x89,0x98,0xb3,0x6a,0x1e,0xc9,0xc2,0x08,0x0b,0x88,0x21,0x79,0x00,0x84,0x02,0x10,0x89,0x98,0x91,
|
||||
0x7b,0x1e,0xc8,0xc2,0x80,0x1a,0x09,0x01,0x31,0x31,0x04,0x04,0x48,0x1b,0xe8,0xb5,0x20,0x2f,0x9a,0xb1,
|
||||
0x08,0x0a,0xa1,0x84,0x60,0x29,0x82,0x03,0x28,0x8a,0xb8,0xd6,0x92,0x3b,0x0f,0xa8,0x90,0x09,0xa0,0x95,
|
||||
0x42,0x59,0x00,0x92,0x01,0x89,0x39,0x0c,0xf1,0xc2,0x88,0x8b,0x8a,0x1a,0x18,0x04,0x15,0x23,0x13,0x22,
|
||||
0x3a,0x8e,0x81,0x4c,0x9c,0xf1,0xa0,0x0a,0x1b,0x09,0x11,0x32,0x35,0x33,0x13,0x02,0x89,0x1f,0xf1,0xc3,
|
||||
0x29,0x0f,0xa8,0xa1,0x28,0x2a,0x92,0x15,0x40,0x18,0x92,0x92,0x89,0x28,0x2f,0xca,0xf4,0x91,0x2a,0x0b,
|
||||
0x90,0x83,0x22,0x31,0x22,0x32,0x29,0x9a,0x8b,0xf6,0xa2,0x3c,0x8e,0xc0,0x80,0x2a,0xa0,0x86,0x31,0x59,
|
||||
0x80,0x92,0x81,0x8a,0x80,0x4c,0x8c,0xf1,0xa1,0x09,0x0a,0x90,0x12,0x51,0x40,0x10,0x93,0x93,0x09,0x1d,
|
||||
0xf2,0xb3,0x3a,0x8f,0xb0,0xa1,0x29,0x08,0x04,0x42,0x48,0x81,0x93,0x08,0xab,0x82,0x4f,0x9c,0xf3,0x80,
|
||||
0x1a,0x99,0x82,0x30,0x48,0x02,0x85,0x01,0x19,0x8a,0x9a,0xe6,0x93,0x4b,0x8c,0xc0,0x80,0x09,0x91,0x23,
|
||||
0x70,0x10,0x82,0x01,0x0a,0xba,0x82,0x3f,0xab,0xf3,0x08,0x0b,0xa8,0x11,0x30,0x04,0x25,0x48,0x08,0xb1,
|
||||
0x88,0x2e,0xe1,0x93,0x5b,0x8c,0xc1,0x00,0x2b,0x90,0x04,0x50,0x18,0x92,0x01,0x8a,0xe0,0x21,0x3e,0xa9,
|
||||
0xd4,0x00,0x0b,0xa8,0x10,0x4a,0x01,0x15,0x30,0x00,0xa2,0x89,0x9d,0xd1,0x18,0x1c,0xc0,0x92,0x09,0x98,
|
||||
0x02,0x58,0x00,0x85,0x22,0x29,0x98,0xb0,0x19,0xf2,0x82,0x2e,0xac,0xd1,0x08,0x1a,0x11,0x33,0x14,0x04,
|
||||
0x10,0x99,0xb9,0x9a,0x3c,0xd2,0x96,0x29,0x8d,0xb9,0x99,0x88,0x42,0x70,0x11,0x82,0x82,0x89,0x8b,0xaa,
|
||||
0xb0,0x87,0x40,0x0d,0xc8,0x98,0x8a,0x18,0x40,0x32,0x14,0x02,0x00,0x9a,0xba,0xa9,0x98,0x37,0x3c,0xe9,
|
||||
0xc0,0x99,0x8a,0x38,0x41,0x14,0x13,0x11,0x09,0x0c,0x9a,0x88,0x10,0x7a,0xd4,0xa2,0x0d,0xab,0x88,0x00,
|
||||
0x24,0x51,0x10,0x01,0x09,0x98,0x08,0x19,0x90,0xa0,0x79,0xa9,0xf4,0xaa,0xaa,0x29,0x38,0x25,0x52,0x18,
|
||||
0x81,0xa1,0x81,0x39,0x1c,0xa8,0xf0,0x38,0xf2,0x00,0x8e,0xb1,0x98,0x11,0x61,0x28,0x92,0x11,0x19,0x29,
|
||||
0x0b,0xd2,0xa0,0xb8,0xb9,0x77,0x2d,0xc8,0x90,0x98,0x11,0x38,0x85,0x12,0x08,0x2b,0xaa,0xb4,0x01,0x1b,
|
||||
0xca,0xf2,0xa1,0x77,0x1b,0xd0,0x88,0x99,0x31,0x48,0x02,0x80,0xe1,0x28,0x1b,0x92,0x91,0x92,0x2f,0x8c,
|
||||
0x01,0x79,0xb7,0x10,0x8d,0x88,0x88,0x85,0x30,0x88,0x09,0xb9,0x83,0x3a,0x92,0x2a,0xf9,0x00,0x98,0x23,
|
||||
0x7d,0xe3,0xa2,0xaa,0x10,0x4a,0x83,0x12,0xa8,0x1a,0x9c,0x84,0x20,0xa0,0x98,0xaa,0x39,0x29,0x06,0x58,
|
||||
0xb7,0x4b,0x9e,0x00,0x80,0x15,0x19,0xa0,0x99,0xa1,0x50,0x19,0x00,0xaa,0x88,0x0a,0x04,0x31,0x3a,0x7f,
|
||||
0xf3,0x80,0x0b,0x38,0x88,0x87,0x08,0x89,0x1b,0xb2,0x23,0x08,0x2a,0xad,0x91,0x21,0x41,0x89,0xe1,0x79,
|
||||
0xe2,0x00,0xaa,0x21,0x19,0x15,0x89,0xa1,0x0c,0x80,0x48,0xa2,0x10,0xbb,0x88,0x88,0x17,0x29,0x98,0xca,
|
||||
0x57,0x0d,0xb0,0x09,0x82,0x60,0x80,0x80,0xc8,0x10,0x1a,0x12,0x98,0x91,0x0d,0x08,0x10,0x94,0x18,0x99,
|
||||
0x3c,0x07,0x3d,0xdb,0x08,0xa2,0x44,0x08,0x90,0xc9,0x82,0x5b,0x10,0x98,0xc1,0x09,0x19,0x38,0xa3,0x83,
|
||||
0xab,0x5c,0x07,0x2c,0xea,0x08,0x80,0x43,0x80,0x81,0xbb,0x81,0x19,0x05,0x19,0xc0,0x8a,0x80,0x69,0x91,
|
||||
0x01,0xa9,0x39,0x37,0x2f,0xdb,0x08,0x91,0x63,0x08,0x80,0xb9,0x01,0x3b,0x12,0xa8,0xd3,0x1b,0x89,0x11,
|
||||
0xa7,0x11,0x8b,0xb0,0x77,0x0a,0xc8,0x8a,0x81,0x50,0x01,0x00,0xb8,0x29,0x0a,0x12,0xa1,0x91,0x8f,0x90,
|
||||
0x10,0x23,0x2b,0xb8,0x9a,0x77,0xe2,0xa2,0x8d,0x18,0x28,0x05,0x18,0x99,0x8a,0xa1,0x31,0x81,0x89,0xe9,
|
||||
0x18,0x00,0x31,0xa0,0x08,0xac,0x70,0xa7,0x00,0xae,0x18,0x00,0x25,0x90,0x08,0xac,0x11,0x00,0x13,0x9b,
|
||||
0x99,0x0d,0x03,0x01,0x94,0x0c,0x89,0x39,0x77,0x1b,0xcb,0x8a,0x84,0x51,0x00,0x89,0xb8,0x28,0x01,0x20,
|
||||
0xe1,0x09,0x99,0x30,0xa3,0x02,0xba,0x4d,0x1a,0x57,0x8b,0xbb,0x8d,0x05,0x21,0x11,0x8c,0xa8,0x18,0x13,
|
||||
0x29,0xb8,0xac,0x01,0x69,0x01,0x89,0xb8,0x19,0x41,0x77,0x9b,0xaa,0x8b,0x15,0x31,0x82,0xac,0x90,0x28,
|
||||
0x33,0x99,0xe1,0x9a,0x30,0x39,0x94,0xc8,0x08,0x2b,0x61,0x27,0x8d,0xab,0x8b,0x07,0x11,0x01,0x9c,0x80,
|
||||
0x00,0x23,0x8a,0x99,0xbb,0x24,0x01,0x21,0xae,0x18,0x88,0x34,0x47,0x9e,0x99,0x8b,0x16,0x01,0x00,0xbb,
|
||||
0x01,0x82,0x52,0x9a,0x9a,0xc0,0x42,0x10,0x0a,0xf0,0x00,0x20,0x4a,0x07,0xbb,0x8a,0x8c,0x34,0x82,0x10,
|
||||
0xbc,0x28,0x93,0x33,0xc8,0x0d,0x98,0x21,0x03,0x8b,0xb8,0x1c,0x53,0x10,0x57,0xbc,0x9a,0xaa,0x36,0x01,
|
||||
0x18,0xca,0x18,0x02,0x40,0xb0,0x9b,0x88,0x49,0x04,0xa9,0x90,0x9c,0x42,0x11,0x77,0xba,0x8a,0xab,0x53,
|
||||
0x02,0x28,0xc9,0x09,0x03,0x40,0x81,0x9d,0xa0,0x08,0x43,0x99,0x90,0xda,0x31,0x28,0x77,0xb9,0x9a,0xba,
|
||||
0x42,0x13,0x20,0xc8,0x0b,0x12,0x31,0x86,0xab,0xa8,0x8a,0x34,0x90,0x18,0xbd,0x29,0x92,0x77,0xa2,0xac,
|
||||
0xd9,0x28,0x22,0x20,0xb2,0xab,0x30,0x59,0x33,0xc8,0xa8,0xbb,0x40,0x10,0x11,0xf0,0x89,0x88,0x71,0x87,
|
||||
0xa9,0xb9,0x0d,0x21,0x11,0x04,0xb9,0x08,0x08,0x63,0x81,0x88,0xc9,0x0b,0x11,0x30,0x83,0xbd,0x99,0x1b,
|
||||
0x77,0x91,0x9a,0xdc,0x08,0x02,0x42,0x81,0x9a,0xa0,0x38,0x44,0x28,0xa1,0xfa,0x88,0x19,0x30,0xa1,0xa0,
|
||||
0xe9,0x78,0x82,0x98,0xf8,0x8a,0x18,0x38,0x04,0xa1,0x92,0x0c,0x40,0x00,0x04,0xb1,0x1a,0x8c,0x29,0xb2,
|
||||
0x83,0x98,0x2f,0x07,0x98,0xb8,0x9f,0x09,0x88,0x15,0x00,0x18,0x9a,0x10,0x94,0x43,0x00,0x3a,0xc9,0x80,
|
||||
0xa2,0x38,0x1a,0x8e,0x61,0xa5,0xa0,0xbc,0x8e,0x88,0x81,0x23,0x89,0x82,0x2a,0x11,0x12,0x07,0x10,0x10,
|
||||
0x1a,0x81,0x80,0x02,0x0a,0xb9,0x77,0x92,0x8c,0xbf,0x98,0x98,0x22,0x19,0x29,0x9b,0x13,0x12,0x15,0x00,
|
||||
0x31,0x5a,0x11,0x94,0xa5,0x82,0x49,0x2c,0x57,0xab,0xa0,0x9d,0x02,0xa1,0x5a,0x1d,0x0a,0xb2,0xa3,0x84,
|
||||
0x2a,0x0a,0x2f,0x82,0x96,0x99,0x68,0x4b,0x08,0xc1,0xa1,0x02,0x79,0x99,0x38,0xd9,0x12,0xc8,0x10,0x1c,
|
||||
0x18,0xc0,0xb3,0x92,0x7a,0x3a,0x1a,0xb1,0x84,0x93,0x10,0x8c,0x7a,0xa0,0x08,0xa8,0x4a,0xa8,0x1a,0xf4,
|
||||
0x00,0x01,0x38,0x29,0x1c,0x82,0xb0,0x95,0xb3,0x20,0x1f,0x8a,0x92,0xd1,0x98,0x33,0x48,0x0e,0x18,0x21,
|
||||
0xa0,0xc8,0x92,0x58,0x08,0x9f,0x94,0x08,0x82,0x1f,0x30,0x0a,0xc4,0xa0,0x12,0x29,0x99,0xaa,0x95,0x12,
|
||||
0xc9,0x10,0x08,0x16,0x9e,0x22,0x1c,0xb3,0x0b,0x10,0x78,0x98,0x88,0x88,0x00,0x87,0x0c,0x81,0x19,0xc4,
|
||||
0x08,0x20,0x3c,0xa8,0xe2,0x93,0x11,0x3b,0x0c,0x82,0xa1,0xb2,0x2b,0x79,0x89,0xf2,0x82,0x18,0x88,0x11,
|
||||
0x1b,0x20,0x9e,0x94,0x09,0x01,0x2c,0x90,0x13,0xf0,0x48,0x80,0x29,0x0b,0x4b,0xd1,0x10,0xb0,0x7e,0xa0,
|
||||
0x80,0xd3,0x10,0x82,0x4c,0x89,0xa0,0xb3,0x92,0x08,0x38,0x8b,0xf5,0x01,0x92,0x29,0x8c,0x84,0xa2,0x1b,
|
||||
0x38,0x7a,0x8a,0xa8,0xa4,0x20,0x08,0x0f,0xa4,0x90,0x94,0x1c,0x33,0x0f,0x00,0x09,0x92,0xd0,0x02,0x1a,
|
||||
0x80,0xb3,0x28,0x28,0x0f,0x92,0x88,0x82,0x2c,0xa1,0x13,0xf0,0x40,0x9a,0x95,0x98,0x18,0x80,0x3b,0x3f,
|
||||
0x4b,0xb1,0x91,0x11,0x3f,0x18,0x8a,0xa2,0xa0,0x04,0x2a,0x6c,0x1c,0x28,0x9a,0xb4,0x38,0x40,0x0f,0x81,
|
||||
0xb0,0x84,0x8b,0x52,0x0d,0x10,0x90,0x11,0xd8,0x20,0xc0,0x20,0xe2,0x10,0x81,0x4b,0x2c,0xa8,0x93,0x6a,
|
||||
0x88,0x88,0xe3,0x28,0x88,0x18,0xb0,0x02,0x59,0x80,0x0e,0x03,0x19,0xb0,0x0e,0x80,0x15,0xca,0x41,0x08,
|
||||
0x3a,0xb9,0x2e,0xa5,0x09,0x80,0x08,0x24,0xcb,0x85,0x8c,0x13,0xb0,0x1a,0x84,0x2f,0x12,0x9d,0xa2,0x10,
|
||||
0x86,0x0a,0xa8,0x4c,0x83,0x8a,0xc1,0x38,0x22,0x9b,0xca,0xa2,0x07,0x09,0x3b,0x88,0x04,0xd8,0x1b,0x95,
|
||||
0x01,0x91,0x99,0x98,0x7b,0x49,0xa8,0xa1,0xc4,0x7b,0x18,0x0a,0xb1,0xc4,0x12,0x1c,0x59,0xc8,0x82,0xb2,
|
||||
0x49,0x0a,0x4c,0xd2,0x91,0x83,0x19,0x20,0x0f,0x91,0x98,0x23,0xc8,0x18,0x90,0x4c,0x01,0xa9,0xa5,0x08,
|
||||
0x21,0x9a,0xa9,0x3b,0x85,0xb3,0x82,0xb8,0xb8,0x06,0x7a,0x0a,0x99,0xb0,0x34,0x01,0x4b,0xea,0xa3,0xa5,
|
||||
0x4b,0x1a,0x1b,0xa6,0x90,0x08,0x2c,0x41,0xd2,0x90,0xa4,0x29,0x20,0x0e,0x93,0xc0,0x99,0x28,0x38,0x89,
|
||||
0x14,0x12,0x48,0x08,0xc0,0x9a,0x18,0xbf,0x11,0xc8,0x48,0x9a,0x4b,0x14,0x10,0x13,0xa9,0x70,0xa2,0xad,
|
||||
0xa0,0xbb,0x48,0x02,0x21,0x04,0x1a,0x39,0x99,0x85,0x82,0x19,0xbb,0xeb,0x91,0x18,0x4a,0x98,0xb0,0x84,
|
||||
0x29,0x58,0x81,0xb2,0x77,0xa4,0x9f,0x90,0x99,0x51,0x10,0x08,0x92,0xa9,0x58,0x00,0x88,0xa3,0xba,0x1b,
|
||||
0x99,0x90,0x07,0x98,0x29,0x19,0x1a,0x05,0x92,0x28,0xa9,0x77,0xb5,0xaf,0x10,0x88,0x30,0x14,0xa9,0x19,
|
||||
0xa8,0x18,0x16,0x98,0x89,0x99,0x8b,0x22,0x82,0x29,0x89,0x9d,0x81,0x13,0x62,0x00,0xba,0xc0,0x77,0xa3,
|
||||
0xbf,0x08,0x00,0x40,0x22,0xc8,0x98,0x00,0x29,0x14,0xc2,0x9a,0x1a,0x0c,0x12,0x94,0x99,0x19,0x8a,0x12,
|
||||
0x07,0x88,0x2b,0x9a,0xb2,0x77,0x94,0xdc,0x09,0x10,0x20,0x22,0xc0,0x8b,0x30,0x00,0x13,0xb1,0xaf,0x19,
|
||||
0x82,0x11,0x01,0xbc,0x98,0x14,0x20,0x20,0xba,0x9c,0x31,0x30,0x7a,0x57,0xfb,0x0b,0x21,0x82,0x11,0x90,
|
||||
0x9e,0x11,0x03,0x08,0x09,0xbc,0x08,0x15,0x08,0x09,0xb9,0x88,0x63,0x00,0x9a,0x90,0x98,0x51,0x10,0xba,
|
||||
0x77,0xa1,0xbf,0x28,0x13,0x00,0x00,0xd9,0x1a,0x43,0xa1,0x98,0x99,0x8b,0x53,0x93,0xab,0x1a,0x80,0x22,
|
||||
0x14,0xcb,0x0b,0x22,0x82,0x10,0x9a,0x9f,0x77,0xd2,0x9e,0x11,0x03,0x08,0x08,0xba,0x28,0x35,0xa9,0xab,
|
||||
0x01,0x18,0x60,0x90,0xbb,0x20,0x32,0x0a,0x88,0xe8,0x18,0x42,0x08,0xaa,0xc8,0x28,0x77,0xd2,0x9f,0x21,
|
||||
0x12,0x89,0x89,0x98,0x38,0x43,0xc8,0xab,0x21,0x11,0x18,0xb0,0xdb,0x48,0x33,0xc0,0xaa,0x28,0x28,0x12,
|
||||
0xa0,0x9e,0x39,0x84,0x71,0x97,0xec,0x19,0x33,0x91,0xaa,0x08,0x18,0x41,0xa3,0xcc,0x2a,0x23,0xa1,0x98,
|
||||
0x8a,0x8a,0x16,0x82,0x9c,0x09,0x83,0x02,0x18,0xac,0x98,0x15,0xa1,0x77,0xc0,0x9f,0x20,0x14,0x99,0x8a,
|
||||
0x81,0x01,0x22,0xa8,0xae,0x11,0x23,0xa9,0x99,0x98,0x20,0x24,0xb8,0xac,0x30,0x23,0x89,0xa9,0xb9,0x50,
|
||||
0x51,0x49,0x67,0xfa,0x0d,0x31,0x02,0xaa,0x1a,0x10,0x11,0x12,0xe9,0x9b,0x42,0x83,0xb9,0x8a,0x18,0x21,
|
||||
0x83,0xd8,0x8b,0x31,0x04,0xa8,0x9a,0x08,0x12,0x86,0x59,0x57,0xfa,0x8d,0x32,0x02,0xba,0x09,0x11,0x02,
|
||||
0x11,0xba,0xad,0x33,0x14,0xab,0x8c,0x81,0x13,0x10,0xab,0xba,0x34,0x33,0xcb,0xab,0x22,0x42,0x09,0x6a,
|
||||
0x77,0xe9,0x8d,0x31,0x84,0xa9,0x1a,0x11,0x81,0x02,0x9a,0x8d,0x21,0x04,0x9a,0x8c,0x00,0x03,0x10,0x8c,
|
||||
0xa9,0x03,0x14,0x0a,0xab,0x92,0x14,0x10,0xab,0x77,0xc5,0xaf,0x30,0x14,0x99,0x9b,0x11,0x03,0x01,0x99,
|
||||
0xbb,0x11,0x26,0x98,0xac,0x08,0x13,0x82,0xaa,0x9b,0x31,0x43,0xb8,0xcb,0x41,0x32,0xb9,0xd8,0x77,0x93,
|
||||
0xef,0x18,0x32,0x90,0x9c,0x10,0x12,0x18,0x99,0xa9,0x10,0x52,0x88,0xcb,0x08,0x41,0x00,0xb9,0x99,0x30,
|
||||
0x22,0xb0,0xc9,0x29,0x51,0x81,0xb9,0x77,0x94,0xcf,0x29,0x43,0xa0,0xab,0x20,0x22,0x08,0xa0,0xba,0x49,
|
||||
0x53,0xb0,0xd9,0x18,0x21,0x80,0xb8,0x99,0x48,0x21,0xc1,0xb8,0x19,0x68,0x02,0xd1,0x72,0x84,0xdf,0x08,
|
||||
0x24,0x98,0xaa,0x20,0x12,0x08,0x88,0xba,0x20,0x44,0x98,0xac,0x18,0x31,0x18,0xaa,0xba,0x30,0x25,0xb0,
|
||||
0xbb,0x38,0x61,0x80,0xc8,0x77,0x92,0xcf,0x18,0x33,0xa0,0xac,0x11,0x12,0x00,0x98,0xaa,0x28,0x35,0xb0,
|
||||
0xbc,0x10,0x23,0x90,0xaa,0x9b,0x30,0x16,0xa0,0x9c,0x18,0x05,0x81,0x1b,0x77,0xc2,0xbf,0x30,0x14,0xb8,
|
||||
0x8b,0x21,0x12,0x10,0x99,0x9d,0x30,0x15,0xa9,0xab,0x21,0x21,0x98,0xca,0x80,0x32,0x82,0xca,0x99,0x41,
|
||||
0x21,0xb8,0x78,0x77,0xfb,0x0a,0x42,0x81,0xba,0x18,0x21,0x01,0x81,0xbb,0x0c,0x35,0x81,0xac,0x1a,0x12,
|
||||
0x01,0x89,0xbb,0x08,0x35,0x81,0xad,0x88,0x04,0x11,0x1b,0x77,0xd2,0xae,0x20,0x14,0xa8,0x8b,0x11,0x12,
|
||||
0x10,0xa8,0xbc,0x51,0x23,0xca,0x9a,0x11,0x12,0x88,0xb9,0x8b,0x30,0x33,0xa1,0xe9,0x09,0x51,0x01,0x70,
|
||||
0x17,0xfc,0x0b,0x43,0xa2,0xaa,0x19,0x22,0x01,0x81,0xcb,0x2b,0x45,0x91,0xac,0x19,0x31,0x80,0xb8,0xb9,
|
||||
0x28,0x44,0xa1,0xcb,0x18,0x42,0x80,0x49,0x57,0xf9,0x8c,0x31,0x83,0xba,0x1a,0x03,0x02,0x21,0xca,0x9c,
|
||||
0x53,0x02,0xcb,0x09,0x11,0x00,0x80,0xc9,0x0a,0x62,0x00,0xba,0x19,0x22,0x00,0x19,0x77,0xd3,0xaf,0x20,
|
||||
0x14,0x99,0x8b,0x01,0x12,0x30,0xa9,0xad,0x41,0x23,0xca,0x9a,0x11,0x20,0x80,0xc9,0x0b,0x68,0x02,0xb9,
|
||||
0x8a,0x21,0x12,0x91,0x77,0xa4,0xde,0x08,0x43,0x98,0x9a,0x00,0x11,0x21,0x90,0xdb,0x28,0x34,0xa8,0xab,
|
||||
0x08,0x21,0x01,0xb1,0x9f,0x3a,0x33,0xb0,0xbb,0x4a,0x21,0x93,0x74,0x17,0xed,0x0a,0x42,0x91,0xa9,0x08,
|
||||
0x10,0x12,0x93,0xca,0x1b,0x34,0x93,0xca,0x0a,0x28,0x21,0xa1,0xdb,0x0a,0x22,0x83,0xc9,0x8b,0x10,0x06,
|
||||
0x70,0x27,0xfa,0x8c,0x31,0x02,0xaa,0x0a,0x10,0x22,0x13,0xca,0x9c,0x42,0x13,0x9a,0x9c,0x00,0x31,0x00,
|
||||
0xe9,0xa9,0x40,0x11,0xb8,0xa9,0x39,0x68,0x78,0x07,0xe9,0x0c,0x30,0x83,0xb9,0x1a,0x18,0x12,0x04,0xa9,
|
||||
0x8d,0x31,0x14,0x9a,0x9b,0x00,0x22,0x02,0xda,0xab,0x31,0x33,0xbb,0xbc,0x01,0x61,0x79,0x27,0xfa,0x0c,
|
||||
0x30,0x82,0x99,0x0a,0x08,0x03,0x15,0x9a,0x8d,0x22,0x12,0x8a,0xaa,0x80,0x41,0x30,0xea,0x99,0x20,0x21,
|
||||
0xa9,0xa9,0x1b,0x58,0x71,0x37,0xfb,0x0d,0x21,0x92,0xa8,0x09,0x88,0x22,0x24,0xba,0x9c,0x23,0x23,0x0a,
|
||||
0xc9,0xc0,0x41,0x30,0xc9,0xc8,0x20,0x28,0x88,0xb0,0x1c,0x0a,0x73,0x17,0xeb,0x1b,0x21,0x92,0x08,0x8a,
|
||||
0xba,0x34,0x24,0xab,0xa9,0x04,0x30,0x20,0xd0,0x99,0x69,0x10,0xa0,0x98,0x0a,0x28,0x11,0xaa,0x9c,0x08,
|
||||
0x79,0x17,0xdd,0x28,0x00,0x90,0x82,0xba,0x39,0x24,0x90,0x09,0x80,0x01,0x16,0xa8,0x08,0x30,0x4a,0x19,
|
||||
0xa9,0xb8,0x96,0x00,0x1c,0x9a,0x98,0x01,0x7f,0xc7,0x99,0x11,0x1a,0x80,0xb0,0x29,0x23,0xa8,0x11,0x2a,
|
||||
0x93,0xa7,0x92,0x69,0x2a,0x88,0x91,0x2a,0x88,0xb2,0x89,0xe0,0x25,0x8f,0x32,0x8f,0x2a,0xc2,0xa5,0x18,
|
||||
0x39,0x8f,0x84,0xa0,0x10,0xa0,0x01,0x41,0x2d,0x09,0xc2,0x90,0x82,0xf3,0x88,0x31,0x9c,0x32,0xba,0xa1,
|
||||
0x83,0x88,0xa7,0x3c,0x22,0x1f,0xc5,0x91,0x21,0x1e,0x90,0xb2,0x11,0x2b,0xc0,0x81,0x97,0x5a,0x1a,0xb8,
|
||||
0xa3,0x94,0x1b,0x83,0x0b,0x18,0x98,0x30,0xf5,0x28,0x91,0x7b,0xa8,0xd3,0x93,0x10,0x2e,0x88,0xb1,0x13,
|
||||
0x1e,0x01,0xe1,0x21,0x89,0x3a,0xc0,0x48,0xc0,0x80,0x94,0x90,0x21,0x0d,0x10,0x91,0x0a,0xb2,0x39,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0x00,0x88,0x00,0x08,0x08,0x08,0x08,0x88,0x80,0x80,
|
||||
0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
static constexpr VoiceClip gpsOffClip = {
|
||||
gpsOffData, sizeof(gpsOffData), 9237, 8000
|
||||
};
|
||||
}} // namespace mesh::audio
|
||||
+183
-2
@@ -1,6 +1,51 @@
|
||||
#include "Arduino.h"
|
||||
#ifdef PIN_BUZZER
|
||||
#include "buzzer.h"
|
||||
#if MESH_GPS_VOICE
|
||||
#if defined(MESH_GPS_VOICE_G726_BITRATE)
|
||||
// Board source filters already compile this player entry point. Keep the
|
||||
// experimental decoder out of ordinary images and avoid changing every
|
||||
// board's filter just for the hardware comparison.
|
||||
#include "g726/g726_decoder.c"
|
||||
#include "G726VoiceData.h"
|
||||
#else
|
||||
#include "ButtonVoiceData.h"
|
||||
#include "GpsVoiceData.h"
|
||||
#endif
|
||||
#include "nrf52/GpsVoicePlayer.h"
|
||||
static mesh::audio::GpsVoicePlayer gps_voice;
|
||||
extern "C" void PWM3_IRQHandler() { gps_voice.interrupt(); }
|
||||
|
||||
static mesh::audio::VoiceClip buttonVoiceClip(ButtonVoicePrompt prompt) {
|
||||
using namespace mesh::audio;
|
||||
switch (prompt) {
|
||||
case ButtonVoicePrompt::Ready: return readyClip;
|
||||
case ButtonVoicePrompt::NotificationCleared: return notificationClearedClip;
|
||||
case ButtonVoicePrompt::AdvertQueued: return advertQueuedClip;
|
||||
case ButtonVoicePrompt::AdvertFailed: return advertFailedClip;
|
||||
case ButtonVoicePrompt::SoundOn: return soundOnClip;
|
||||
case ButtonVoicePrompt::SoundOff: return soundOffClip;
|
||||
case ButtonVoicePrompt::GpsOn: return gpsOnClip;
|
||||
case ButtonVoicePrompt::GpsOff: return gpsOffClip;
|
||||
case ButtonVoicePrompt::ActionFailed: return actionFailedClip;
|
||||
case ButtonVoicePrompt::UsbSetup: return usbSetupClip;
|
||||
case ButtonVoicePrompt::ShuttingDown: return shuttingDownClip;
|
||||
case ButtonVoicePrompt::Restarting: return restartingClip;
|
||||
#ifdef HAS_DRV2605
|
||||
case ButtonVoicePrompt::AlertsSoundVibration: return alertsSoundVibrationClip;
|
||||
case ButtonVoicePrompt::AlertsSoundOnly: return alertsSoundOnlyClip;
|
||||
case ButtonVoicePrompt::AlertsVibrationOnly: return alertsVibrationOnlyClip;
|
||||
case ButtonVoicePrompt::AlertsSilent: return alertsSilentClip;
|
||||
#else
|
||||
case ButtonVoicePrompt::AlertsSoundVibration:
|
||||
case ButtonVoicePrompt::AlertsSoundOnly:
|
||||
case ButtonVoicePrompt::AlertsVibrationOnly:
|
||||
case ButtonVoicePrompt::AlertsSilent: return {};
|
||||
#endif
|
||||
}
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
void genericBuzzer::begin() {
|
||||
// Serial.print("DBG: Setting up buzzer on pin ");
|
||||
@@ -16,9 +61,14 @@ void genericBuzzer::begin() {
|
||||
}
|
||||
|
||||
void genericBuzzer::play(const char *melody) {
|
||||
#if MESH_GPS_VOICE
|
||||
// A muted ordinary alert must not cancel the one courtesy confirmation
|
||||
// that may still be queued or playing while the preference is quiet.
|
||||
if (_is_quiet) return;
|
||||
#endif
|
||||
if (isPlaying()) // interrupt existing
|
||||
{
|
||||
rtttl::stop();
|
||||
stop();
|
||||
}
|
||||
|
||||
if (_is_quiet) return;
|
||||
@@ -36,19 +86,149 @@ void genericBuzzer::playNotification(const char* melody) {
|
||||
rtttl::begin(PIN_BUZZER, melody);
|
||||
}
|
||||
|
||||
void genericBuzzer::stopNotification() {
|
||||
#if MESH_GPS_VOICE
|
||||
// Notification timers own their tones, not user-requested confirmations.
|
||||
// Preserve a pending direction tone, speech gap, or active voice clip.
|
||||
if (_voice_pending || gps_voice.active()) return;
|
||||
#endif
|
||||
stop();
|
||||
}
|
||||
|
||||
bool genericBuzzer::speakGps(bool enabled) {
|
||||
return speakButton(enabled ? ButtonVoicePrompt::GpsOn : ButtonVoicePrompt::GpsOff);
|
||||
}
|
||||
|
||||
bool genericBuzzer::speakButton(ButtonVoicePrompt prompt, bool allowQuiet) {
|
||||
const char* melody = nullptr;
|
||||
switch (prompt) {
|
||||
case ButtonVoicePrompt::GpsOn:
|
||||
melody = startup_song;
|
||||
break;
|
||||
case ButtonVoicePrompt::GpsOff:
|
||||
case ButtonVoicePrompt::ShuttingDown:
|
||||
case ButtonVoicePrompt::Restarting:
|
||||
melody = shutdown_song;
|
||||
break;
|
||||
case ButtonVoicePrompt::Ready:
|
||||
case ButtonVoicePrompt::NotificationCleared:
|
||||
case ButtonVoicePrompt::AdvertQueued:
|
||||
case ButtonVoicePrompt::AdvertFailed:
|
||||
case ButtonVoicePrompt::SoundOn:
|
||||
case ButtonVoicePrompt::SoundOff:
|
||||
case ButtonVoicePrompt::ActionFailed:
|
||||
case ButtonVoicePrompt::UsbSetup:
|
||||
case ButtonVoicePrompt::AlertsSoundVibration:
|
||||
case ButtonVoicePrompt::AlertsSoundOnly:
|
||||
case ButtonVoicePrompt::AlertsVibrationOnly:
|
||||
case ButtonVoicePrompt::AlertsSilent:
|
||||
#if MESH_GPS_VOICE && !defined(HAS_DRV2605)
|
||||
// Reject unavailable modes before cancelling any valid audio.
|
||||
if (prompt >= ButtonVoicePrompt::AlertsSoundVibration) return false;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
stop();
|
||||
if (_is_quiet && !allowQuiet) return true;
|
||||
#if !MESH_GPS_VOICE
|
||||
// The UI retains its legacy acknowledgements on untested boards. New
|
||||
// voice-only prompts must not introduce tones there (including Ready).
|
||||
if (!melody) return true;
|
||||
#endif
|
||||
#ifdef PIN_BUZZER_EN
|
||||
digitalWrite(PIN_BUZZER_EN, HIGH);
|
||||
#endif
|
||||
#if MESH_GPS_VOICE
|
||||
_voice_prompt = prompt;
|
||||
_voice_pending = true;
|
||||
_voice_allow_quiet = allowQuiet;
|
||||
_voice_gap_started = false;
|
||||
#endif
|
||||
// Preserve the recognisable rising/falling control tone even where voice
|
||||
// playback is disabled. Optional tones release their PWM before speech.
|
||||
if (melody) rtttl::begin(PIN_BUZZER, melody);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef MESH_BUTTON_AUDIO_HIL
|
||||
void genericBuzzer::voiceStatus(char* reply, size_t size) {
|
||||
#if MESH_GPS_VOICE
|
||||
snprintf(reply, size, "voice playing=%u started=%lu completed=%lu cancelled=%lu samples=%lu quiet=%u gain=%u pending=%u tone=%u",
|
||||
gps_voice.playing(), (unsigned long)gps_voice.started(),
|
||||
(unsigned long)gps_voice.completed(), (unsigned long)gps_voice.cancelled(),
|
||||
(unsigned long)gps_voice.played(), _is_quiet, gps_voice.gain(),
|
||||
_voice_pending, rtttl::isPlaying());
|
||||
#else
|
||||
snprintf(reply, size, "voice unsupported");
|
||||
#endif
|
||||
}
|
||||
bool genericBuzzer::voiceGain(uint8_t gain) {
|
||||
#if MESH_GPS_VOICE
|
||||
return !_voice_pending && gps_voice.setGain(gain);
|
||||
#else
|
||||
(void)gain;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void genericBuzzer::stop() {
|
||||
rtttl::stop();
|
||||
#if MESH_GPS_VOICE
|
||||
_voice_pending = false;
|
||||
_voice_allow_quiet = false;
|
||||
_voice_gap_started = false;
|
||||
gps_voice.stop();
|
||||
#endif
|
||||
#ifdef PIN_BUZZER_EN
|
||||
if (_is_quiet) digitalWrite(PIN_BUZZER_EN, LOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool genericBuzzer::isPlaying() {
|
||||
#if MESH_GPS_VOICE
|
||||
if (_voice_pending || gps_voice.active()) return true;
|
||||
#endif
|
||||
return rtttl::isPlaying();
|
||||
}
|
||||
|
||||
void genericBuzzer::loop() {
|
||||
if (!rtttl::done()) rtttl::play();
|
||||
#if MESH_GPS_VOICE
|
||||
gps_voice.service();
|
||||
if (gps_voice.playing()) return;
|
||||
if (_voice_pending) {
|
||||
if (!rtttl::done()) {
|
||||
rtttl::play();
|
||||
return;
|
||||
}
|
||||
if (!_voice_gap_started) {
|
||||
rtttl::stop();
|
||||
_voice_gap_ms = millis();
|
||||
_voice_gap_started = true;
|
||||
}
|
||||
if (static_cast<uint32_t>(millis() - _voice_gap_ms) < 100) return;
|
||||
_voice_pending = false;
|
||||
_voice_gap_started = false;
|
||||
if (!_is_quiet || _voice_allow_quiet)
|
||||
gps_voice.start(buttonVoiceClip(_voice_prompt));
|
||||
_voice_allow_quiet = false;
|
||||
if (gps_voice.playing()) return;
|
||||
}
|
||||
#endif
|
||||
if (!rtttl::done()) {
|
||||
rtttl::play();
|
||||
return;
|
||||
}
|
||||
// Courtesy mute/unmute speech can temporarily power the driver while the
|
||||
// preference stays quiet. Return both pins to their low-power state.
|
||||
if (_is_quiet) {
|
||||
digitalWrite(PIN_BUZZER, LOW);
|
||||
#ifdef PIN_BUZZER_EN
|
||||
digitalWrite(PIN_BUZZER_EN, LOW);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void genericBuzzer::startup() {
|
||||
@@ -60,6 +240,7 @@ void genericBuzzer::shutdown() {
|
||||
}
|
||||
|
||||
void genericBuzzer::quiet(bool buzzer_state) {
|
||||
if (buzzer_state) stop();
|
||||
_is_quiet = buzzer_state;
|
||||
#ifdef PIN_BUZZER_EN
|
||||
if (_is_quiet) {
|
||||
|
||||
@@ -2,6 +2,29 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <NonBlockingRtttl.h>
|
||||
#include "ButtonVoice.h"
|
||||
|
||||
// Screenless Full Companions share spoken button confirmations. Keep an
|
||||
// explicit board list: a configured buzzer on a screened board is not an
|
||||
// opt-in, and the Wio joystick/display profiles retain their existing tones.
|
||||
// ThinkNode M4 is excluded until its buzzer wiring is verified: its current
|
||||
// PIN_BUZZER/PIN_BUZZER_EN overlap I2C SDA and a battery-status LED.
|
||||
// R1 Neo has no flash fitted; its dummy QSPI SCK aliases the buzzer, so a
|
||||
// profile which opts into QSPIFLASH must not also default to spoken audio.
|
||||
// Retain the existing prerecorded clips; intelligibility still needs physical
|
||||
// qualification on each board. MESH_GPS_VOICE=0 is an explicit opt-out.
|
||||
#ifndef MESH_GPS_VOICE
|
||||
#if defined(NRF52_PLATFORM) && defined(PIN_BUZZER) \
|
||||
&& defined(COMPANION_RADIO_FULL) && COMPANION_RADIO_FULL \
|
||||
&& (defined(T1000_E) || defined(RAK_WISMESH_TAG) \
|
||||
|| defined(MESH_TRACKER_X1) \
|
||||
|| (defined(R1Neo) && !defined(QSPIFLASH)) \
|
||||
|| defined(THINKNODE_M3))
|
||||
#define MESH_GPS_VOICE 1
|
||||
#else
|
||||
#define MESH_GPS_VOICE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* class abstracts underlying RTTTL library
|
||||
|
||||
@@ -22,6 +45,13 @@ class genericBuzzer
|
||||
void begin(); // set up buzzer port
|
||||
void play(const char *melody); // Generic play function
|
||||
void playNotification(const char* melody);
|
||||
void stopNotification(); // background alert cancellation must not cut off control speech
|
||||
bool speakGps(bool enabled); // direction tones, then optional spoken confirmation
|
||||
bool speakButton(ButtonVoicePrompt prompt, bool allowQuiet = false);
|
||||
#ifdef MESH_BUTTON_AUDIO_HIL
|
||||
void voiceStatus(char* reply, size_t size);
|
||||
bool voiceGain(uint8_t gain);
|
||||
#endif
|
||||
void stop();
|
||||
void loop(); // loop driven-nonblocking
|
||||
void startup(); // play startup sound
|
||||
@@ -36,4 +66,11 @@ class genericBuzzer
|
||||
const char *shutdown_song = "Shutdown:d=4,o=5,b=100:8g5,16e5,16c5";
|
||||
|
||||
bool _is_quiet = true;
|
||||
#if MESH_GPS_VOICE
|
||||
bool _voice_pending = false;
|
||||
ButtonVoicePrompt _voice_prompt = ButtonVoicePrompt::Ready;
|
||||
bool _voice_allow_quiet = false;
|
||||
bool _voice_gap_started = false;
|
||||
uint32_t _voice_gap_ms = 0;
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,502 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* This source code is a product of Sun Microsystems, Inc. and is provided
|
||||
* for unrestricted use. Users may copy or modify this source code without
|
||||
* charge.
|
||||
*
|
||||
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
|
||||
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun source code is provided with no support and without any obligation on
|
||||
* the part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/* Decoder-only adaptation for MeshCore experiments, 2026.
|
||||
* Common code and G.723-24 tables: Sun source at codec-g7xx commit
|
||||
* 2ebdfe0c76670c6f887542fd4c291afbab988cdc, src/g72x.c and src/g723_24.c.
|
||||
* G.726-16 tables: Marc Randolph's 16 kbps adaptation, libsndfile commit
|
||||
* b9103bd48b6c8fb517ae737fe3baee0c718b804c, src/G72x/g723_16.c.
|
||||
* Encoder, A-law/u-law conversion and heap/block interfaces are removed.
|
||||
* Sun fmult rounding (+0x30) is preserved. Negative left shifts are replaced
|
||||
* by multiplication. State widths are fixed, rather than native long/short.
|
||||
*/
|
||||
/* MIX interpolation adapted from FFmpeg n7.1 libavcodec/g726.c.
|
||||
* Copyright (c) 2004 Roman Shaposhnik.
|
||||
* The MIX adaptation is under GNU LGPL version 2.1 or (at your option) later.
|
||||
* This combined experimental source is distributed under that LGPL license;
|
||||
* the original Sun unrestricted-use notice is retained above.
|
||||
* See COPYING.LGPLv2.1 next to this source. No production codec change is made.
|
||||
* Corrected fractional MIX matches FFmpeg sample-for-sample; this does not
|
||||
* constitute independent ITU conformance qualification.
|
||||
*/
|
||||
#include "g726_decoder.h"
|
||||
|
||||
#if defined(MESH_G726_DECODER_TEST) || \
|
||||
(defined(MESH_BUTTON_AUDIO_HIL) && defined(MESH_GPS_VOICE_G726_BITRATE))
|
||||
|
||||
static const int16_t power2[15] = {
|
||||
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384
|
||||
};
|
||||
#if !defined(MESH_GPS_VOICE_G726_BITRATE) || MESH_GPS_VOICE_G726_BITRATE == 16
|
||||
static const int16_t dqln16[4] = {116, 365, 365, 116};
|
||||
static const int16_t wi16[4] = {-704, 14048, 14048, -704};
|
||||
static const int16_t fi16[4] = {0, 0xe00, 0xe00, 0};
|
||||
#endif
|
||||
#if !defined(MESH_GPS_VOICE_G726_BITRATE) || MESH_GPS_VOICE_G726_BITRATE == 24
|
||||
static const int16_t dqln24[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048};
|
||||
static const int16_t wi24[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128};
|
||||
static const int16_t fi24[8] = {0, 0x200, 0x400, 0xe00, 0xe00, 0x400, 0x200, 0};
|
||||
#endif
|
||||
|
||||
static int quan(int value)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 15; ++i)
|
||||
if (value < power2[i]) break;
|
||||
return i;
|
||||
}
|
||||
|
||||
static int fmult(int an, int srn)
|
||||
{
|
||||
int16_t anmag = (int16_t)(an > 0 ? an : ((-an) & 0x1fff));
|
||||
int16_t anexp = (int16_t)(quan(anmag) - 6);
|
||||
int16_t anmant = (int16_t)(anmag == 0 ? 32 : anexp >= 0
|
||||
? anmag >> anexp : anmag * (1 << -anexp));
|
||||
int16_t wanexp = (int16_t)(anexp + ((srn >> 6) & 15) - 13);
|
||||
int16_t wanmant = (int16_t)((anmant * (srn & 63) + 0x30) >> 4);
|
||||
int16_t retval = (int16_t)(wanexp >= 0
|
||||
? (wanmant * (1 << wanexp)) & 0x7fff
|
||||
: wanmant >> -wanexp);
|
||||
return (an ^ srn) < 0 ? -retval : retval;
|
||||
}
|
||||
|
||||
void g726_init(G726State *s)
|
||||
{
|
||||
unsigned i;
|
||||
s->yl = 34816;
|
||||
s->yu = 544;
|
||||
s->dms = s->dml = s->ap = 0;
|
||||
for (i = 0; i < 2; ++i) {
|
||||
s->a[i] = s->pk[i] = 0;
|
||||
s->sr[i] = 32;
|
||||
}
|
||||
for (i = 0; i < 6; ++i) {
|
||||
s->b[i] = 0;
|
||||
s->dq[i] = 32;
|
||||
}
|
||||
s->td = 0;
|
||||
}
|
||||
|
||||
static int predictor_zero(const G726State *s)
|
||||
{
|
||||
int i, sezi = fmult(s->b[0] >> 2, s->dq[0]);
|
||||
for (i = 1; i < 6; ++i) sezi += fmult(s->b[i] >> 2, s->dq[i]);
|
||||
return sezi;
|
||||
}
|
||||
|
||||
static int predictor_pole(const G726State *s)
|
||||
{
|
||||
return fmult(s->a[1] >> 2, s->sr[1]) + fmult(s->a[0] >> 2, s->sr[0]);
|
||||
}
|
||||
|
||||
static int step_size(const G726State *s)
|
||||
{
|
||||
if (s->ap >= 256) return s->yu;
|
||||
/* Retain fractional yl before the final shift, rather than truncating it
|
||||
* first and applying the Sun reference's negative-difference rounding. */
|
||||
return (s->yl + (s->yu - (s->yl >> 6)) * (s->ap >> 2)) >> 6;
|
||||
}
|
||||
|
||||
static int reconstruct(int sign, int dqln, int y)
|
||||
{
|
||||
int16_t dql = (int16_t)(dqln + (y >> 2));
|
||||
int16_t dex, dqt, dq;
|
||||
if (dql < 0) return sign ? -32768 : 0;
|
||||
dex = (dql >> 7) & 15;
|
||||
dqt = 128 + (dql & 127);
|
||||
dq = (int16_t)((dqt * 128) >> (14 - dex));
|
||||
return sign ? dq - 32768 : dq;
|
||||
}
|
||||
|
||||
static int magnitude(int value) { return value < 0 ? -value : value; }
|
||||
|
||||
static void update(int y, int wi, int fi, int dq, int sr, int dqsez, G726State *s)
|
||||
{
|
||||
int cnt;
|
||||
int16_t mag, exp, a2p = 0, a1ul, pks1, fa1;
|
||||
int16_t ylint, ylfrac, thr1, thr2, dqthr, pk0;
|
||||
int8_t tr;
|
||||
pk0 = dqsez < 0 ? 1 : 0;
|
||||
mag = dq & 0x7fff;
|
||||
ylint = (int16_t)(s->yl >> 15);
|
||||
ylfrac = (s->yl >> 10) & 31;
|
||||
thr1 = (int16_t)((32 + ylfrac) * (1 << ylint));
|
||||
thr2 = ylint > 9 ? 31 * 1024 : thr1;
|
||||
dqthr = (thr2 + (thr2 >> 1)) >> 1;
|
||||
tr = s->td != 0 && mag > dqthr;
|
||||
|
||||
s->yu = (int16_t)(y + ((wi - y) >> 5));
|
||||
if (s->yu < 544) s->yu = 544;
|
||||
else if (s->yu > 5120) s->yu = 5120;
|
||||
s->yl += s->yu + ((-s->yl) >> 6);
|
||||
|
||||
if (tr) {
|
||||
s->a[0] = s->a[1] = 0;
|
||||
for (cnt = 0; cnt < 6; ++cnt) s->b[cnt] = 0;
|
||||
} else {
|
||||
pks1 = pk0 ^ s->pk[0];
|
||||
a2p = (int16_t)(s->a[1] - (s->a[1] >> 7));
|
||||
if (dqsez != 0) {
|
||||
fa1 = pks1 ? s->a[0] : (int16_t)-s->a[0];
|
||||
if (fa1 < -8191) a2p -= 256;
|
||||
else if (fa1 > 8191) a2p += 255;
|
||||
else a2p += fa1 >> 5;
|
||||
if (pk0 ^ s->pk[1]) {
|
||||
if (a2p <= -12160) a2p = -12288;
|
||||
else if (a2p >= 12416) a2p = 12288;
|
||||
else a2p -= 128;
|
||||
} else {
|
||||
if (a2p <= -12416) a2p = -12288;
|
||||
else if (a2p >= 12160) a2p = 12288;
|
||||
else a2p += 128;
|
||||
}
|
||||
}
|
||||
s->a[1] = a2p;
|
||||
s->a[0] -= s->a[0] >> 8;
|
||||
if (dqsez != 0) s->a[0] += pks1 == 0 ? 192 : -192;
|
||||
a1ul = 15360 - a2p;
|
||||
if (s->a[0] < -a1ul) s->a[0] = (int16_t)-a1ul;
|
||||
else if (s->a[0] > a1ul) s->a[0] = a1ul;
|
||||
for (cnt = 0; cnt < 6; ++cnt) {
|
||||
s->b[cnt] -= s->b[cnt] >> 8;
|
||||
if (dq & 0x7fff) s->b[cnt] += (dq ^ s->dq[cnt]) >= 0 ? 128 : -128;
|
||||
}
|
||||
}
|
||||
for (cnt = 5; cnt > 0; --cnt) s->dq[cnt] = s->dq[cnt - 1];
|
||||
if (mag == 0) s->dq[0] = dq >= 0 ? 32 : -992;
|
||||
else {
|
||||
exp = (int16_t)quan(mag);
|
||||
s->dq[0] = (int16_t)(exp * 64 + ((mag * 64) >> exp) - (dq >= 0 ? 0 : 1024));
|
||||
}
|
||||
s->sr[1] = s->sr[0];
|
||||
if (sr == 0) s->sr[0] = 32;
|
||||
else if (sr > 0) {
|
||||
exp = (int16_t)quan(sr);
|
||||
s->sr[0] = (int16_t)(exp * 64 + ((sr * 64) >> exp));
|
||||
} else if (sr > -32768) {
|
||||
mag = (int16_t)-sr;
|
||||
exp = (int16_t)quan(mag);
|
||||
s->sr[0] = (int16_t)(exp * 64 + ((mag * 64) >> exp) - 1024);
|
||||
} else s->sr[0] = -992;
|
||||
s->pk[1] = s->pk[0];
|
||||
s->pk[0] = pk0;
|
||||
s->td = !tr && a2p < -11776;
|
||||
s->dms += (fi - s->dms) >> 5;
|
||||
s->dml += (fi * 4 - s->dml) >> 7;
|
||||
if (tr) s->ap = 256;
|
||||
else if (y < 1536 || s->td == 1 || magnitude(s->dms * 4 - s->dml) >= (s->dml >> 3))
|
||||
s->ap += (512 - s->ap) >> 4;
|
||||
else s->ap += (-s->ap) >> 4;
|
||||
}
|
||||
|
||||
int16_t g726_decode(G726State *s, uint8_t code, uint8_t bits)
|
||||
{
|
||||
int16_t sezi, sei, sez, se, y, sr, dq, dqsez;
|
||||
const int16_t *dqln, *wi, *fi;
|
||||
int sign;
|
||||
if (bits == 2) {
|
||||
#if !defined(MESH_GPS_VOICE_G726_BITRATE) || MESH_GPS_VOICE_G726_BITRATE == 16
|
||||
code &= 3;
|
||||
sign = code & 2;
|
||||
dqln = dqln16; wi = wi16; fi = fi16;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else if (bits == 3) {
|
||||
#if !defined(MESH_GPS_VOICE_G726_BITRATE) || MESH_GPS_VOICE_G726_BITRATE == 24
|
||||
code &= 7;
|
||||
sign = code & 4;
|
||||
dqln = dqln24; wi = wi24; fi = fi24;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else return 0;
|
||||
sezi = (int16_t)predictor_zero(s);
|
||||
sez = sezi >> 1;
|
||||
sei = (int16_t)(sezi + predictor_pole(s));
|
||||
se = sei >> 1;
|
||||
y = (int16_t)step_size(s);
|
||||
dq = (int16_t)reconstruct(sign, dqln[code], y);
|
||||
sr = (int16_t)(dq < 0 ? se - (dq & 0x3fff) : se + dq);
|
||||
dqsez = (int16_t)(sr - se + sez);
|
||||
update(y, wi[code], fi[code], dq, sr, dqsez, s);
|
||||
return (int16_t)(sr * 4);
|
||||
}
|
||||
|
||||
|
||||
#endif /* experimental decoder only */
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef MESH_G726_EXPERIMENTAL_DECODER_H
|
||||
#define MESH_G726_EXPERIMENTAL_DECODER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Experimental Sun G.72x decoder with LGPL FFmpeg MIX interpolation.
|
||||
* See g726_decoder.c and COPYING.LGPLv2.1 for attribution and license.
|
||||
* All fields have explicit MCU-width types; state and code require no heap. */
|
||||
typedef struct {
|
||||
int32_t yl;
|
||||
int16_t yu, dms, dml, ap;
|
||||
int16_t a[2], b[6], pk[2], dq[6], sr[2];
|
||||
int8_t td;
|
||||
} G726State;
|
||||
|
||||
void g726_init(G726State *state);
|
||||
/* bits=2 for G.726-16; bits=3 for G.726-24. No packing or allocation here. */
|
||||
int16_t g726_decode(G726State *state, uint8_t code, uint8_t bits);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,174 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <HardwarePWM.h>
|
||||
#include <helpers/ui/GpsVoice.h>
|
||||
|
||||
namespace mesh { namespace audio {
|
||||
|
||||
class GpsVoicePlayer {
|
||||
static constexpr uint32_t OWNER = 0x63696f56; // Voic
|
||||
static constexpr size_t BLOCK = 128;
|
||||
#if defined(MESH_BUTTON_AUDIO_HIL) && ((defined(MESH_GPS_VOICE_BINARY_DRIVE) && MESH_GPS_VOICE_BINARY_DRIVE) || (defined(MESH_GPS_VOICE_PDM_DRIVE) && MESH_GPS_VOICE_PDM_DRIVE) || (defined(MESH_GPS_VOICE_PCM32_DRIVE) && !MESH_GPS_VOICE_PCM32_DRIVE))
|
||||
static constexpr uint16_t TOP = 250; // 64 kHz carrier
|
||||
#else
|
||||
static constexpr uint16_t TOP = 500; // tested 32 kHz carrier and output
|
||||
#endif
|
||||
VoiceDecoder decoder_;
|
||||
VoiceInterpolator interpolator_;
|
||||
alignas(4) uint16_t buffers_[2][BLOCK] = {};
|
||||
uint16_t lengths_[2] = {};
|
||||
bool last_[2] = {};
|
||||
bool owned_ = false;
|
||||
volatile bool playing_ = false;
|
||||
volatile uint32_t played_ = 0;
|
||||
volatile uint32_t completed_ = 0;
|
||||
uint32_t started_ = 0;
|
||||
uint32_t cancelled_ = 0;
|
||||
uint8_t gain_ = 8; // acoustically selected drive for the T1000-E buzzer
|
||||
#if defined(MESH_BUTTON_AUDIO_HIL) && defined(MESH_GPS_VOICE_BINARY_DRIVE) && MESH_GPS_VOICE_BINARY_DRIVE
|
||||
// Acoustic experiment: full GPIO-level drive with a small hysteresis band.
|
||||
// Unlike carrier PWM, silence holds a constant level instead of chattering.
|
||||
bool binary_level_ = false;
|
||||
#endif
|
||||
#if defined(MESH_BUTTON_AUDIO_HIL) && defined(MESH_GPS_VOICE_PDM_DRIVE) && MESH_GPS_VOICE_PDM_DRIVE
|
||||
int32_t density_error_ = 0;
|
||||
int32_t held_pcm_ = 0;
|
||||
bool density_repeat_ = false;
|
||||
#endif
|
||||
|
||||
void fill(unsigned n) {
|
||||
const uint32_t before = decoder_.position();
|
||||
for (size_t i = 0; i < BLOCK; ++i) {
|
||||
#if defined(MESH_BUTTON_AUDIO_HIL) && defined(MESH_GPS_VOICE_PDM_DRIVE) && MESH_GPS_VOICE_PDM_DRIVE
|
||||
// Twice the reconstruction rate: full-width pulses instead of narrow
|
||||
// duty-cycle pulses. Error feedback moves quantization noise upwards.
|
||||
if (!density_repeat_) held_pcm_ = interpolator_.next(decoder_) * gain_;
|
||||
density_repeat_ = !density_repeat_;
|
||||
int32_t pcm = held_pcm_;
|
||||
#else
|
||||
int32_t pcm = interpolator_.next(decoder_) * gain_;
|
||||
#endif
|
||||
if (pcm > 32767) pcm = 32767;
|
||||
if (pcm < -32768) pcm = -32768;
|
||||
#if defined(MESH_BUTTON_AUDIO_HIL) && defined(MESH_GPS_VOICE_PDM_DRIVE) && MESH_GPS_VOICE_PDM_DRIVE
|
||||
density_error_ += pcm;
|
||||
const bool high = density_error_ >= 0;
|
||||
density_error_ -= high ? 32767 : -32768;
|
||||
buffers_[n][i] = 0x8000 | (high ? TOP : 0);
|
||||
#elif defined(MESH_BUTTON_AUDIO_HIL) && defined(MESH_GPS_VOICE_BINARY_DRIVE) && MESH_GPS_VOICE_BINARY_DRIVE
|
||||
if (pcm > 1024) binary_level_ = true;
|
||||
else if (pcm < -1024) binary_level_ = false;
|
||||
buffers_[n][i] = 0x8000 | (binary_level_ ? TOP : 0);
|
||||
#else
|
||||
buffers_[n][i] = 0x8000 | ((pcm + 32768) * TOP / 65536);
|
||||
#endif
|
||||
}
|
||||
lengths_[n] = decoder_.position() - before;
|
||||
last_[n] = decoder_.done();
|
||||
}
|
||||
void finishFromInterrupt() {
|
||||
NRF_PWM3->INTENCLR = 0xffffffff;
|
||||
NRF_PWM3->SHORTS = 0;
|
||||
NRF_PWM3->ENABLE = 0;
|
||||
digitalWrite(PIN_BUZZER, LOW);
|
||||
playing_ = false;
|
||||
++completed_;
|
||||
}
|
||||
public:
|
||||
bool start(VoiceClip clip) {
|
||||
stop();
|
||||
#if defined(MESH_GPS_VOICE_G726_BITRATE)
|
||||
if (!clip.valid() || !HwPWM3.takeOwnership(OWNER)) return false;
|
||||
#else
|
||||
if (!clip.data || !clip.samples || clip.samples > clip.bytes * 2
|
||||
|| (clip.sample_rate != 8000 && clip.sample_rate != 16000)
|
||||
|| !HwPWM3.takeOwnership(OWNER)) return false;
|
||||
#endif
|
||||
owned_ = true;
|
||||
if (!HwPWM3.addPin(PIN_BUZZER)) { stop(); return false; }
|
||||
decoder_.begin(clip);
|
||||
interpolator_.begin(clip.sample_rate);
|
||||
#if defined(MESH_BUTTON_AUDIO_HIL) && defined(MESH_GPS_VOICE_BINARY_DRIVE) && MESH_GPS_VOICE_BINARY_DRIVE
|
||||
binary_level_ = false;
|
||||
#endif
|
||||
#if defined(MESH_BUTTON_AUDIO_HIL) && defined(MESH_GPS_VOICE_PDM_DRIVE) && MESH_GPS_VOICE_PDM_DRIVE
|
||||
density_error_ = held_pcm_ = 0;
|
||||
density_repeat_ = false;
|
||||
#endif
|
||||
fill(0);
|
||||
fill(1);
|
||||
played_ = 0;
|
||||
NRF_PWM3->ENABLE = 0;
|
||||
NRF_PWM3->MODE = PWM_MODE_UPDOWN_Up;
|
||||
NRF_PWM3->COUNTERTOP = TOP;
|
||||
NRF_PWM3->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_1;
|
||||
NRF_PWM3->DECODER = PWM_DECODER_LOAD_Common;
|
||||
NRF_PWM3->LOOP = 1;
|
||||
NRF_PWM3->SHORTS = PWM_SHORTS_LOOPSDONE_SEQSTART0_Msk;
|
||||
for (unsigned i = 0; i < 2; ++i) {
|
||||
NRF_PWM3->SEQ[i].PTR = reinterpret_cast<uintptr_t>(buffers_[i]);
|
||||
NRF_PWM3->SEQ[i].CNT = BLOCK;
|
||||
#if defined(MESH_BUTTON_AUDIO_HIL) && !(defined(MESH_GPS_VOICE_PDM_DRIVE) && MESH_GPS_VOICE_PDM_DRIVE) && ((defined(MESH_GPS_VOICE_BINARY_DRIVE) && MESH_GPS_VOICE_BINARY_DRIVE) || (defined(MESH_GPS_VOICE_PCM32_DRIVE) && !MESH_GPS_VOICE_PCM32_DRIVE))
|
||||
NRF_PWM3->SEQ[i].REFRESH = 1;
|
||||
#else
|
||||
NRF_PWM3->SEQ[i].REFRESH = 0;
|
||||
#endif
|
||||
NRF_PWM3->SEQ[i].ENDDELAY = 0;
|
||||
NRF_PWM3->EVENTS_SEQEND[i] = 0;
|
||||
NRF_PWM3->EVENTS_SEQSTARTED[i] = 0;
|
||||
}
|
||||
NRF_PWM3->EVENTS_STOPPED = 0;
|
||||
NRF_PWM3->EVENTS_LOOPSDONE = 0;
|
||||
NVIC_ClearPendingIRQ(PWM3_IRQn);
|
||||
NVIC_SetPriority(PWM3_IRQn, 7); // below SoftDevice/radio interrupts
|
||||
NRF_PWM3->INTENSET = PWM_INTENSET_SEQEND0_Msk | PWM_INTENSET_SEQEND1_Msk;
|
||||
playing_ = true;
|
||||
++started_;
|
||||
NRF_PWM3->ENABLE = 1;
|
||||
NVIC_EnableIRQ(PWM3_IRQn);
|
||||
NRF_PWM3->TASKS_SEQSTART[0] = 1;
|
||||
return true;
|
||||
}
|
||||
void interrupt() {
|
||||
for (unsigned i = 0; i < 2; ++i) {
|
||||
if (!NRF_PWM3->EVENTS_SEQEND[i]) continue;
|
||||
NRF_PWM3->EVENTS_SEQEND[i] = 0;
|
||||
if (!playing_) continue;
|
||||
played_ += lengths_[i];
|
||||
if (last_[i]) { finishFromInterrupt(); break; }
|
||||
fill(i); // refill the inactive buffer; no allocation or blocking in IRQ
|
||||
}
|
||||
}
|
||||
void service() { if (owned_ && !playing_) stop(); }
|
||||
void stop() {
|
||||
if (!owned_) return;
|
||||
NVIC_DisableIRQ(PWM3_IRQn);
|
||||
NRF_PWM3->INTENCLR = 0xffffffff;
|
||||
NRF_PWM3->SHORTS = 0;
|
||||
NRF_PWM3->ENABLE = 0;
|
||||
NVIC_ClearPendingIRQ(PWM3_IRQn);
|
||||
if (playing_) ++cancelled_;
|
||||
playing_ = false;
|
||||
HwPWM3.removePin(PIN_BUZZER);
|
||||
HwPWM3.releaseOwnership(OWNER);
|
||||
digitalWrite(PIN_BUZZER, LOW);
|
||||
owned_ = false;
|
||||
}
|
||||
bool playing() const { return playing_; }
|
||||
bool active() const { return owned_; } // includes deferred IRQ-completion cleanup
|
||||
#ifdef MESH_BUTTON_AUDIO_HIL
|
||||
bool setGain(uint8_t gain) {
|
||||
if (active() || gain < 1 || gain > 8) return false;
|
||||
gain_ = gain;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
uint8_t gain() const { return gain_; }
|
||||
uint32_t played() const { return played_; }
|
||||
uint32_t started() const { return started_; }
|
||||
uint32_t completed() const { return completed_; }
|
||||
uint32_t cancelled() const { return cancelled_; }
|
||||
};
|
||||
|
||||
}} // namespace mesh::audio
|
||||
Reference in new issue
Block a user