diff --git a/MicroDexed.ino b/MicroDexed.ino index a1c12ef..3843ac4 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -21,9 +21,6 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "TeensyTimerTool.h" -using namespace TeensyTimerTool; - #include #include "config.h" #include @@ -32,7 +29,9 @@ using namespace TeensyTimerTool; #include #include #include -#include +#include +#include +using namespace TeensyTimerTool; #include "midi_devices.hpp" #include "synth_dexed.h" #include "dexed_sd.h" @@ -96,7 +95,8 @@ AudioMixer4 audio_thru_mixer_l; // Drumset #if NUM_DRUMS > 0 -AudioPlayMemory* Drum[NUM_DRUMS]; +//AudioPlayMemory* Drum[NUM_DRUMS]; +AudioPlayArrayResmp* Drum[NUM_DRUMS]; #if NUM_DRUMS < 5 AudioMixer4 drum_mixer_r; AudioMixer4 drum_mixer_l; @@ -283,7 +283,10 @@ void create_audio_dexed_chain(uint8_t instance_id) #if NUM_DRUMS > 0 void create_audio_drum_chain(uint8_t instance_id) { - Drum[instance_id] = new AudioPlayMemory(); + //Drum[instance_id] = new AudioPlayMemory(); + Drum[instance_id] = new AudioPlayArrayResmp(); + Drum[instance_id]->enableInterpolation(false); + Drum[instance_id]->setPlaybackRate(1.0); dynamicConnections[nDynamic++] = new AudioConnection(*Drum[instance_id], 0, drum_mixer_r, instance_id); dynamicConnections[nDynamic++] = new AudioConnection(*Drum[instance_id], 0, drum_mixer_l, instance_id); @@ -839,8 +842,16 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) drum_reverb_send_mixer_r.gain(slot, (1.0 - pan) * volume_transform(drum_config[d].reverb_send)); drum_reverb_send_mixer_l.gain(slot, pan * volume_transform(drum_config[d].reverb_send)); #endif - if (drum_config[d].drum_data != NULL) - Drum[slot]->play(drum_config[d].drum_data); + if (drum_config[d].drum_data != NULL && drum_config[d].len > 0) + { + //Drum[slot]->play(drum_config[d].drum_data); + if (drum_config[d].pitch != 0.0) + { + Drum[slot]->enableInterpolation(true); + Drum[slot]->setPlaybackRate(drum_config[d].pitch); + } + Drum[slot]->playRaw(drum_config[d].drum_data, drum_config[d].len, 1); + } #ifdef DEBUG Serial.print(F("Drum ")); @@ -872,7 +883,11 @@ uint8_t drum_get_slot(uint8_t dt) for (uint8_t i = 0; i < NUM_DRUMS; i++) { if (!Drum[i]->isPlaying()) + { drum_type[i] = DRUM_NONE; + Drum[i]->enableInterpolation(false); + Drum[i]->setPlaybackRate(1.0); + } else { if (drum_type[i] == dt) @@ -884,6 +899,7 @@ uint8_t drum_get_slot(uint8_t dt) Serial.println(dt); #endif Drum[i]->stop(); + return (i); } } diff --git a/dexed_sd.cpp b/dexed_sd.cpp index e935a21..395cb71 100644 --- a/dexed_sd.cpp +++ b/dexed_sd.cpp @@ -482,6 +482,7 @@ bool load_sd_drumsettings_json(uint8_t number, uint8_t target) for (uint8_t i = 0; i < NUM_DRUMSET_CONFIG; i++) { + drum_config[i].pitch = data_json["pitch"][i] ; drum_config[i].pan = data_json["pan"][i] ; drum_config[i].vol_max = data_json["vol_max"][i] ; drum_config[i].vol_min = data_json["vol_min"][i] ; @@ -541,6 +542,7 @@ bool save_sd_drumsettings_json(uint8_t number, uint8_t target) for (uint8_t i = 0; i < NUM_DRUMSET_CONFIG; i++) { + data_json["pitch"][i] = drum_config[i].pitch; data_json["pan"][i] = drum_config[i].pan; data_json["vol_max"][i] = drum_config[i].vol_max; data_json["vol_min"][i] = drum_config[i].vol_min; diff --git a/drums.h b/drums.h index b18cf98..6419cbb 100644 --- a/drums.h +++ b/drums.h @@ -38,6 +38,8 @@ typedef struct drum_config_s { char name[DRUM_NAME_LEN]; const unsigned int* drum_data; char shortname[2]; // 1 char name for sequencer + uint32_t len; // number of elements in drum_data + float32_t pitch; // float32_t pan; // Panorama (-1.0 - +1.0) float32_t vol_max; // max. Volume (0.0 - 1.0) float32_t vol_min; // min. Volume (0.0 - 1.0, should be <= vol_max) @@ -47,20 +49,22 @@ typedef struct drum_config_s { enum {DRUM_NONE, DRUM_BASS, DRUM_SNARE, DRUM_HIHAT, DRUM_HANDCLAP, DRUM_RIDE, DRUM_CHRASH, DRUM_LOWTOM, DRUM_MIDTOM, DRUM_HIGHTOM, DRUM_PERCUSSION}; // DEFAULT MIDI CHANNEL FOR SAMPLEDRUMS -uint8_t drum_midi_channel=10; +uint8_t drum_midi_channel = 10; drum_config_t drum_config[NUM_DRUMSET_CONFIG] = { - { + { DRUM_BASS, MIDI_A2, "Xrhitom", AudioSampleXrhitom, "B", + 6785, 0.0, - 0.8, 0.0, + 0.8, 0.0, + 0.0 }, { DRUM_BASS, @@ -68,17 +72,21 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Vl1lbeep", AudioSampleVl1lbeepw, "B", + 769, 0.0, - 0.8, 0.0, + 0.8, 0.0, + 0.0 }, - { + { DRUM_BASS, MIDI_B2, "Vl1hbeep", AudioSampleVl1hbeepw, "B", + 513, + 0.0, 0.0, 0.8, 0.0, @@ -90,6 +98,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "bd01", AudioSampleBd01, "B", + 3617, + 0.0, 0.0, 0.8, 0.0, @@ -101,6 +111,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "cp02l", AudioSampleCp02, "C", + 4961, + 0.0, -1.0, 0.6, 0.0, @@ -112,6 +124,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "cp02r", AudioSampleCp02, "C", + 4961, + 0.0, 1.0, 0.6, 0.0, @@ -123,6 +137,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "sd15", AudioSampleSd15, "S", + 3905, + 0.0, 0.2, 0.6, 0.2, @@ -134,6 +150,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "hh01", AudioSampleHh01, "h", + 1441, + 0.0, 0.8, 0.8, 0.3, @@ -145,6 +163,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "hh02", AudioSampleHh02, "h", + 2113, + 0.0, 0.8, 0.8, 0.3, @@ -156,6 +176,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "oh02", AudioSampleOh02, "H", + 6753, + 0.0, 0.8, 0.8, 0.3, @@ -167,6 +189,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "lt01", AudioSampleLt01, "T", + 6817, + 0.0, -0.7, 0.8, 0.0, @@ -178,6 +202,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "ht01", AudioSampleHt01, "T", + 2497, + 0.0, -0.5, 0.8, 0.0, @@ -189,6 +215,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "rd01", AudioSampleRd01, "R", + 15713, + 0.0, -0.6, 0.3, 0.0, @@ -200,6 +228,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "rd02", AudioSampleRd02, "R", + 7681, + 0.0, -0.6, 0.3, 0.0, @@ -211,51 +241,60 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "808Kick", AudioSample808Kick, "B", + 13377, + 0.0, 0.0, 0.8, 0.0, 0.0 }, - { DRUM_BASS, MIDI_C5, "phkick1", AudioSamplePhkick1, "B", + 2433, + 0.0, 0.0, 1.0, 0.0, 0.0 }, - { + { DRUM_SNARE, MIDI_CIS5, "rims1", AudioSampleRims1wav, "R", + 385, + 0.0, -0.2, 0.7, 0.0, 0.0 }, - { + { DRUM_SNARE, MIDI_D5, "Shaker", Shaker, "R", + 897, + 0.0, -0.2, 0.5, 0.0, 0.0 }, - { + { DRUM_SNARE, MIDI_E5, "LNsnare1", AudioSampleLnsnare1, "S", + 5313, + 0.0, 0.0, 0.9, 0.0, @@ -267,17 +306,21 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "LNclap1", AudioSampleLnclap, "C", + 3521, + 0.0, 0.1, 0.9, 0.0, 0.1 }, - { + { DRUM_BASS, MIDI_F5, "Bdtrancy", AudioSampleBdtrancy, "B", + 3969, + 0.0, 0.0, 0.9, 0.0, @@ -289,18 +332,22 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "hhcl1", AudioSampleHhcl1wav, "H", + 3137, + 0.0, 1.0, 0.6, 0.0, 0.0 }, - + { DRUM_BASS, MIDI_G5, "Belltree", AudioSampleBelltree, "B", + 60737, + 0.0, 0.0, 0.7, 0.0, @@ -312,6 +359,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Bongo16", AudioSampleBongo16, "B", + 1633, + 0.0, 0.0, 0.9, 0.0, @@ -323,6 +372,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Bongo27", AudioSampleBongo27, "B", + 5889, + 0.0, 0.0, 0.9, 0.0, @@ -334,6 +385,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Casta", AudioSampleCasta, "B", + 513, + 0.0, 0.0, 0.9, 0.0, @@ -345,18 +398,22 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Cr78kick", AudioSampleCr78kick, "B", + 5057, + 0.0, 0.0, 1.0, 0.0, 0.0 }, - + { DRUM_HIHAT, MIDI_C6, "Cr78tmb1", AudioSampleCr78tmb1, "B", + 3777, + 0.0, 0.0, 0.8, 0.0, @@ -368,6 +425,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Cr78tmb2", AudioSampleCr78tmb2, "B", + 5441, + 0.0, 0.0, 0.8, 0.0, @@ -379,6 +438,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Crash1", AudioSampleCrash1, "B", + 36417, + 0.0, 0.0, 0.9, 0.0, @@ -390,61 +451,73 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Dmpop", AudioSampleDmpop, "B", + 1953, + 0.0, 0.0, 0.9, 0.0, 0.0 - }, + }, { DRUM_BASS, MIDI_E6, "Electr1", AudioSampleElectr1, "B", + 737, + 0.0, 0.0, 0.9, 0.0, 0.0 }, - { + { DRUM_BASS, MIDI_F6, "Excow", AudioSampleExcow, "B", + 5057, + 0.0, 0.0, 0.9, 0.0, 0.0 }, - { + { DRUM_PERCUSSION, MIDI_FIS6, "Tamb", AudioSampleTamb, "T", + 4097, + 0.0, -0.2, 0.6, 0.0, 0.0 }, - { + { DRUM_PERCUSSION, MIDI_GIS6, "Cowbell", AudioSampleCowbell, "S", + 1825, + 0.0, 0.2, 0.6, 0.0, 0.0 - }, + }, { DRUM_HIHAT, MIDI_G6, "660HatC1", AudioSampleHatc1, "T", + 3009, + 0.0, 0.0, 0.6, 0.0, @@ -456,6 +529,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Hhopen1", AudioSampleHhopen1, "S", + 5633, + 0.0, 0.0, 0.6, 0.0, @@ -467,6 +542,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Histicks", AudioSampleHisticks, "S", + 609, + 0.0, 0.0, 0.6, 0.0, @@ -478,29 +555,35 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Hr16snr2", AudioSampleHr16snr2, "S", + 7617, + 0.0, 0.0, 0.6, 0.0, 0.0 }, - - { + + { DRUM_PERCUSSION, MIDI_CIS7, "Tick1", AudioSampleTick1, "S", + 321, + 0.0, 0.0, 0.9, 0.0, 0.0 }, - { + { DRUM_PERCUSSION, MIDI_D7, "M118w", AudioSampleM118w, "S", + 1153, + 0.0, 0.0, 0.9, 0.0, @@ -512,17 +595,21 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Md16_clp", AudioSampleMd16_clp, "S", + 6657, + 0.0, 0.0, 0.9, 0.0, 0.0 }, - { + { DRUM_HIHAT, MIDI_E7, "Ohhwav", AudioSampleOhhwav, "S", + 11777, + 0.0, 0.0, 0.9, 0.0, @@ -534,6 +621,8 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Quijada", AudioSampleQuijada, "S", + 18049, + 0.0, 0.0, 0.9, 0.0, @@ -542,20 +631,24 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = { DRUM_PERCUSSION, MIDI_FIS7, - "tabla1", + "tabla1", AudioSampleR8tabla1, "S", + 7745, + 0.0, 0.0, 0.9, 0.0, 0.0 }, - { + { DRUM_PERCUSSION, MIDI_GIS7, "Ridewav", AudioSampleRidewav, "S", + 10881, + 0.0, 0.0, 0.9, 0.0, @@ -567,17 +660,21 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Scratch1", AudioSampleScratch1, "S", + 1473, + 0.0, 0.0, 0.7, 0.0, 0.0 }, - { + { DRUM_PERCUSSION, MIDI_B7, "Tomlow", AudioSampleTomlow, "S", + 7681, + 0.0, 0.0, 0.9, 0.0, @@ -589,17 +686,21 @@ drum_config_t drum_config[NUM_DRUMSET_CONFIG] = "Tomwav", AudioSampleTomwav, "S", + 3137, + 0.0, 0.0, 0.9, 0.0, 0.0 - }, + }, { DRUM_NONE, 0, "EMPTY", NULL, "-", + 0, + 0.0, 0.0, 0.0, 0.0, diff --git a/third-party/TeensyVariablePlayback/CMakeLists.txt b/third-party/TeensyVariablePlayback/CMakeLists.txt new file mode 100644 index 0000000..ac6d954 --- /dev/null +++ b/third-party/TeensyVariablePlayback/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.5) +project(teensy-variable-playback) +if (NOT DEFINED TEENSY_VERSION) + set(BUILD_FOR_LINUX 1) + add_definitions(-DBUILD_FOR_LINUX) + set(CMAKE_BUILD_TYPE Debug) +endif() + +if (NOT DEFINED BUILD_FOR_LINUX) + import_arduino_library(cores ${COREPATH} avr debug util) + import_arduino_library(SPI ${DEPSPATH}/SPI) + import_arduino_library(SdFat ${DEPSPATH}/SdFat/src common DigitalIO ExFatLib FatLib FsLib iostream SdCard SpiDriver) + import_arduino_library(SD ${DEPSPATH}/SD/src) + import_arduino_library(SerialFlash ${DEPSPATH}/SerialFlash util) + import_arduino_library(Wire ${DEPSPATH}/Wire utility) + import_arduino_library(arm_math ${DEPSPATH}/arm_math/src) + import_arduino_library(Audio ${DEPSPATH}/Audio utility) + add_subdirectory(src) + add_subdirectory(examples) +else() + add_subdirectory(src) + add_subdirectory(test) + add_subdirectory(extras/soundio/save_raw) + add_subdirectory(extras/soundio/save_raw_sd) + add_subdirectory(extras/soundio/save_wav) + add_subdirectory(extras/soundio/sd_play_all) + add_subdirectory(extras/linux/array) + add_subdirectory(extras/linux/sd_raw) +endif() \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/LICENSE b/third-party/TeensyVariablePlayback/LICENSE new file mode 100644 index 0000000..93ec7f5 --- /dev/null +++ b/third-party/TeensyVariablePlayback/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Nic Newdigate + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/third-party/TeensyVariablePlayback/README.md b/third-party/TeensyVariablePlayback/README.md new file mode 100644 index 0000000..f9e3e21 --- /dev/null +++ b/third-party/TeensyVariablePlayback/README.md @@ -0,0 +1,262 @@ +# variable rate playback for teensy audio library +[![Teensy 4.1](https://img.shields.io/badge/project-4.1-brightgreen.svg?label=Teensy&colorA=555555&colorB=ff8aff&logo=)](https://www.pjrc.com/store/teensy41.html) +[![lib-teensy41](https://github.com/newdigate/teensy-variable-playback/actions/workflows/teensy41_lib.yml/badge.svg)](https://github.com/newdigate/teensy-variable-playback/actions/workflows/teensy41_lib.yml) +[![Ubuntu-x64](https://github.com/newdigate/teensy-variable-playback/workflows/Ubuntu-x64/badge.svg)](https://github.com/newdigate/teensy-variable-playback/actions) +[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) +[![CMake](https://img.shields.io/badge/project-CMake-brightgreen.svg?label=built%20with&colorA=555555&colorB=8a8fff&logo=)](CMakelists.txt) +[![made-for-VSCode](https://img.shields.io/badge/Made%20for-VSCode-1f425f.svg)](https://code.visualstudio.com/) +[![Contributors](https://img.shields.io/github/contributors/newdigate/teensy-variable-playback)](https://github.com/newdigate/teensy-variable-playback/graphs/contributors) +[![Commits](https://img.shields.io/github/commit-activity/m/newdigate/teensy-variable-playback)](https://github.com/newdigate/teensy-variable-playback/graphs/contributors) +![s](https://img.shields.io/badge/dynamic/json?color=%23e85b46&label=Patreon&query=data.attributes.patron_count&suffix=%20patrons&url=https%3A%2F%2Fwww.patreon.com%2Fapi%2Fcampaigns%2F4105381) + +play 16-bit PCM raw or wav audio samples at variable playback rates on teensy +* **Note** : this library only works with signed 16-bit integer samples. Floating point samples will not play. + +* for best performance, use SDXC UHS 30MB/sec Application Performance Class 2 (A2) class micro sd-card. + * [sd classes on wikipedia](https://en.wikipedia.org/wiki/SD_card#cite_ref-93) + +## updates +* 25/08/2021: v1.0.12: Skip over RIFF tags in .wav header +* 12/08/2021: v1.0.11: When playing a mono sample, transmit on both channels (credit to @atoktoto) +* 28/07/2021: v1.0.10: Fix issues when starting playback in reverse +* 23/07/2021: v1.0.9: Fix issue which crashes teensy when playing multiple files from SD card using array of filenames +* 21/07/2021: v1.0.8: **Breaking changes** + * ```AudioPlaySdRawResmp``` and ```AudioPlaySdWaveResmp``` merged into a single class ```AudioPlaySdResmp``` + * ```play(...)``` method changed to ```playRaw(...)``` and ```playWav(...)```, specify number of channels in parameters of playRaw +* 13/07/2021: v1.0.7: added multi-channel resampling +* 07/07/2021: v1.0.6: changed to using optimised floating point interpolation, sounds much better +* 30/06/2021: v1.0.5: Optimised quadratic interpolation to use fixed pipeline of 4 samples and use integers instead of floating point +* 25/06/2021: Quadratic interpolation is now working, but is disabled by default + +## contents +* [code structure](#code-structure) +* [requirements](#requirements) +* [usage](#usage) +* [example usage](#example-usage) + +## code structure +| folder | target | description | +|--------|--------------------|------------------------------------------------------------------------------------------------------------------------| +| ```examples``` | ```teensy``` | basic example how to use | +| ```extras``` | ```linux``` | some utils to make life easier | +| ```src``` | ```teensy``` / ```linux``` | extends teensy audio library
* adds ```AudioPlaySdResmp```
* adds ```AudioPlayArrayResmp``` | +| ```test``` | ```linux``` | unit tests that run on linux | + +## requirements +
+ teensy 3.x & 4.x boards + + +
+ with Teensyduino + +```Teensyduino```[^](https://www.pjrc.com/teensy/teensyduino.html) +* This library is built on top of teensy audio library, intended for use with Teensy 3.x and Teensy 4.x boards. +* Install using arduino/teensyduino library manager gui - search ```TeensyVariablePlayback``` + * ![install using arduino library manager](docs/InstallArduino.gif) +
+ + +
+ without Teensyduino (for development) + +```cmake``` ```gcc-arm-none-eabi```[^](https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1) ```teensy-cmake-macros```[^](https://github.com/newdigate/teensy-cmake-macros) ```cores```[^](https://github.com/PaulStoffregen/cores) ```Audio```[^](https://github.com/PaulStoffregen/Audio) ```SD```[^](https://github.com/PaulStoffregen/SD/tree/Juse_Use_SdFat) ```Wire```[^](https://github.com/PaulStoffregen/Wire) ```SPI```[^](https://github.com/PaulStoffregen/SPI) ```SerialFlash```[^](https://github.com/PaulStoffregen/SerialFlash) ```arm_math```[^](https://github.com/PaulStoffregen/arm_math) ```SDFat```[^](https://github.com/greiman/SdFat) +* using [teensy-cmake-macros](https://github.com/newdigate/teensy-cmake-macros), this library can be compiled for teensy 3 and 4 boards without needing Teensyduino. This is mainly used to build the library when a commit is pushed, to verify there are no compile errors. + + +
+ dependencies (click to expand image) + +![dependencies](docs/dependencies.png) + +
+ graphvis (click to expand) + +```dot +graph G { + graph[rankdir="LR"] + "teensy variable playback" -- "teensy-cmake-macros" -- "cmake" [label="dev"] + "teensy-cmake-macros" -- "arm-none-eabi-gcc" [label="dev"] + "PaulStoffregen/Audio.git" -- "PaulStoffregen/cores.git" + "teensy variable playback" -- "PaulStoffregen/Audio.git" + "PaulStoffregen/Audio.git" -- "PaulStoffregen/SD.git@Juse_Use_SdFat" + "PaulStoffregen/SD.git@Juse_Use_SdFat" -- "PaulStoffregen/SPI.git" + "PaulStoffregen/SD.git@Juse_Use_SdFat" -- "greiman/SdFat.git" + "PaulStoffregen/Audio.git" -- "PaulStoffregen/Wire.git" + "PaulStoffregen/Audio.git" -- "PaulStoffregen/SerialFlash.git" + "PaulStoffregen/Audio.git" -- "PaulStoffregen/arm_math.git" +} +``` +
+ +
+ + + +
+ + + + +
+ +
+ linux + +```cmake``` ```gcc or llvm``` ```teensy-x86-stubs```[^](https://github.com/newdigate/teensy-x86-stubs) ```teensy-audio-x86-stubs```[^](https://github.com/newdigate/teensy-audio-x86-stubs) ```teensy-x86-sd-stubs```[^](https://github.com/newdigate/teensy-x86-sd-stubs) ```boost-test``` + +By using stub libraries, we can compile teensy code to native device architecture. To a certain extent, this allows sketches and libraries to be developed, emulated, debugged and unit-tested using linux, on your local device or a build server. In this case I have a few basic tests for the ResamplingSdReader class. + * install boost unit-test library: + * linux: ```sudo apt-get install -yq libboost-test-dev``` + * macos: ```brew install boost``` + +
+ + +## usage +
+ Using with Teensyduino + +* To install the library, use the library manager in Teensyduino (search for ```TeensyVariablePlayback```). Teensyduino should already have all the necessary dependencies pre-installed. + +* Have a look at the examples in the file menu to get started... +
+ +
+ Developing with vscode + + * [Visual Studio Code](https://code.visualstudio.com) + +### clone repo +``` sh +> git clone https://github.com/newdigate/teensy-variable-playback.git +> cd teensy-variable-playback +``` + +## teensy build +You don't need to download or install Teensyduino or Arduino to build the library or examples. Just clone the cores library and any dependencies to a common folder, denoted by ```DEPSPATH``` (in this case ```/home/nic/teensy_libraries```). +
+ clone dependencies (click to expand) + +``` sh + > cd /home/nic/teensy_libraries + > git clone https://github.com/PaulStoffregen/cores.git + > git clone https://github.com/PaulStoffregen/Audio.git + > git clone -b Juse_Use_SdFat https://github.com/PaulStoffregen/SD.git + > git clone https://github.com/PaulStoffregen/Wire.git + > git clone https://github.com/PaulStoffregen/SPI.git + > git clone https://github.com/PaulStoffregen/SerialFlash.git + > git clone https://github.com/PaulStoffregen/arm_math.git + > git clone https://github.com/greiman/SdFat.git +``` + +
+ +
+ update COMPILERPATH and DEPSPATH in cmake/toolchains/teensy41.cmake + +``` cmake +set(COMPILERPATH "/Applications/Arm/bin/") +set(DEPSPATH "/home/nic/teensy_libraries") +set(COREPATH "${DEPSPATH}/cores/teensy4/") +``` + +
+ +
+ build hex file + + * If you run the commands below from the root repository directory, it will build the teensy-variable-playback library and all the examples. + * If you run them from a sub-directory, it will build everything under the sub-directory. (You might need to adjust relative path in ```-DCMAKE_TOOLCHAIN_FILE:FILEPATH``` below) +``` sh +> cd /home/nic/teensy-variable-playback +> mkdir cmake-build-debug +> cd cmake-build-debug +> cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE:FILEPATH="../cmake/toolchains/teensy41.cmake" .. +> make +``` + +
+ +## linux build +### build tests on linux +``` sh +> ./build-linux.sh +``` + +### build tests on win +``` sh +> mkdir cmake-build-debug +> cd cmake-build-debug +> cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE:FILEPATH="../cmake/toolchains/linux.cmake" .. +> make +``` + +### run tests +``` sh +> cmake-build-debug/test/test_suite1 +``` + +## visual studio code + * download vs code + * required extensions + * ms-vscode.cpptools + * optional extensions + * ms-vscode.cmake-tools + * hbenl.vscode-test-explorer + * ms-vscode.test-adapter-converter + * nicnewdigate.boost-test-adapter-debug + * open root folder of repository in visual studio code + * open terminal in visual studio code build, build as above + * (add breakpoint) + * launch + +
+ +## example usage + +
+ example (click to expand) + +```c++ +#include +#include +#include + +// GUItool: begin automatically generated code +AudioPlayArrayResmp rraw_a1; //xy=321,513 +AudioOutputI2S i2s1; //xy=675,518 +AudioConnection patchCord1(rraw_a1, 0, i2s1, 0); +AudioConnection patchCord2(rraw_a1, 0, i2s1, 1); +AudioControlSGTL5000 sgtl5000_1; //xy=521,588 +// GUItool: end automatically generated code + +unsigned char kick_raw[] = { + // ... little-endian 16-bit mono 44100 raw data, generated using linux cmd 'xxd -i kick.raw', raw file saved in Audacity + 0x99, 0x02, 0xd7, 0x02, 0xfa, 0x02, 0x5f, 0x03, 0xc1, 0x03, 0x2a, 0x04, + 0xad, 0x04, 0xa5, 0x05, 0x76, 0x06, 0x2f, 0x07, 0x9e, 0x07, 0xe2, 0x07, + 0x43, 0x08, 0x92, 0x08, 0xb2, 0x08, 0xe8, 0x08, 0x16, 0x09, 0xda, 0x08, + // ... continued ... +}; +unsigned int kick_raw_len = 6350; // length in bytes == numsamples * 2 + +void setup() { + AudioMemory(20); + sgtl5000_1.enable(); + sgtl5000_1.volume(0.5f, 0.5f); + rraw_a1.setPlaybackRate(0.5); + rraw_a1.enableInterpolation(true); +} + +void loop() { + if (!rraw_a1.isPlaying()) { + delay(1000); + rraw_a1.playRaw((int16_t *)kick_raw, kick_raw_len/2, 1); //note: we give number of samples - NOT number of bytes!!!! 1 is for mono (2 for stereo, etc) + } +} +``` + +
+ +# credits +* convert boost test report to junit xml format: [Stuart Lange](https://stackoverflow.com/a/2975928/4634140) diff --git a/third-party/TeensyVariablePlayback/build-linux.sh b/third-party/TeensyVariablePlayback/build-linux.sh new file mode 100644 index 0000000..7e47c58 --- /dev/null +++ b/third-party/TeensyVariablePlayback/build-linux.sh @@ -0,0 +1,6 @@ +#!/bin/bash +rm -rf cmake-build-debug +mkdir cmake-build-debug +cd cmake-build-debug +cmake -DCMAKE_BUILD_TYPE=Debug .. +make \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/build-t41.sh b/third-party/TeensyVariablePlayback/build-t41.sh new file mode 100644 index 0000000..4670068 --- /dev/null +++ b/third-party/TeensyVariablePlayback/build-t41.sh @@ -0,0 +1,6 @@ +#!/bin/bash +rm -rf cmake-build-debug +mkdir cmake-build-debug +cd cmake-build-debug +cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE:FILEPATH="cmake/toolchains/teensy41.cmake" .. +make \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/cmake/install_arduino_library.cmake b/third-party/TeensyVariablePlayback/cmake/install_arduino_library.cmake new file mode 100644 index 0000000..eee38a5 --- /dev/null +++ b/third-party/TeensyVariablePlayback/cmake/install_arduino_library.cmake @@ -0,0 +1,31 @@ +message("installing ardiuno library") +set(ARDUINO_LIBRARY_TARGET "~/Documents/Arduino/Libraries/teensy_variable_playback") + +get_filename_component(DIR_ONE_ABOVE ../../ ABSOLUTE) +message(STATUS ${DIR_ONE_ABOVE}) +set(ARDUINO_LIBRARY_SOURCE ${DIR_ONE_ABOVE}/src/) +set(INSTALL_ARDUINO_CMD "ln -s ${ARDUINO_LIBRARY_SOURCE} ${ARDUINO_LIBRARY_TARGET}") +set(UNINSTALL_ARDUINO_CMD "unlink ${ARDUINO_LIBRARY_TARGET}") + +message(${UNINSTALL_ARDUINO_CMD}) +exec_program( + ${UNINSTALL_ARDUINO_CMD} + OUTPUT_VARIABLE stdout + RETURN_VALUE result +) +message(STATUS ${stdout}) +message(STATUS ${result}) + +message(${INSTALL_ARDUINO_CMD}) +exec_program( + ${INSTALL_ARDUINO_CMD} + OUTPUT_VARIABLE stdout + RETURN_VALUE result +) +message(STATUS ${stdout}) +message(STATUS ${result}) +if (${result} STREQUAL 0) + message("Success...") +else() + message(FATAL_ERROR "Unable to create symbolic link in ${ARDUINO_LIBRARY_TARGET}") +endif() \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/cmake/teensy_variable_playback.cmake.in b/third-party/TeensyVariablePlayback/cmake/teensy_variable_playback.cmake.in new file mode 100644 index 0000000..52c03a3 --- /dev/null +++ b/third-party/TeensyVariablePlayback/cmake/teensy_variable_playback.cmake.in @@ -0,0 +1,9 @@ +set(teensy_variable_playback_VERSION "@teensy_variable_playback_VERSION@") +set(teensy_variable_playback_LIBS teensy_variable_playback -L@LIB_INSTALL_DIR@) + +@PACKAGE_INIT@ + +set_and_check(teensy_variable_playback_INCLUDE_DIR "@INCLUDE_INSTALL_DIR@") +set_and_check(teensy_variable_playback_DIR "@LIB_INSTALL_DIR@") + +check_required_components(teensy_variable_playback) \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/cmake/toolchains/teensy41.cmake b/third-party/TeensyVariablePlayback/cmake/toolchains/teensy41.cmake new file mode 100644 index 0000000..12ba556 --- /dev/null +++ b/third-party/TeensyVariablePlayback/cmake/toolchains/teensy41.cmake @@ -0,0 +1,11 @@ +set(TEENSY_VERSION 41 CACHE STRING "Set to the Teensy version corresponding to your board (30 or 31 allowed)" FORCE) +set(CPU_CORE_SPEED 600000000 CACHE STRING "Set to 24000000, 48000000, 72000000 or 96000000 to set CPU core speed" FORCE) # Derived variables +set(CMAKE_EXE_LINKER_FLAGS "--specs=nosys.specs" CACHE INTERNAL "") +#teensy compiler options +set(COMPILERPATH "/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/") +#set(COMPILERPATH "/Applications/ARM/bin/") +set(DEPSPATH "/home/runner/work/teensy-variable-playback/teensy-variable-playback/deps") +#set(DEPSPATH "/Users/nicholasnewdigate/Development/github/newdigate/temp_dep") +set(COREPATH "${DEPSPATH}/cores/teensy4/") + +find_package(teensy_cmake_macros) diff --git a/third-party/TeensyVariablePlayback/cmake/uninstall.cmake b/third-party/TeensyVariablePlayback/cmake/uninstall.cmake new file mode 100644 index 0000000..a303d93 --- /dev/null +++ b/third-party/TeensyVariablePlayback/cmake/uninstall.cmake @@ -0,0 +1,24 @@ +set(MANIFEST "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt") + +if(NOT EXISTS ${MANIFEST}) + message(FATAL_ERROR "Cannot find install manifest: '${MANIFEST}'") +endif() + +file(STRINGS ${MANIFEST} files) +foreach(file ${files}) + if(EXISTS ${file}) + message(STATUS "Removing file: '${file}'") + + exec_program( + ${CMAKE_COMMAND} ARGS "-E remove ${file}" + OUTPUT_VARIABLE stdout + RETURN_VALUE result + ) + + if(NOT "${result}" STREQUAL 0) + message(FATAL_ERROR "Failed to remove file: '${file}'.") + endif() + else() + MESSAGE(STATUS "File '${file}' does not exist.") + endif() +endforeach(file) \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/docs/InstallArduino.gif b/third-party/TeensyVariablePlayback/docs/InstallArduino.gif new file mode 100644 index 0000000..407543c Binary files /dev/null and b/third-party/TeensyVariablePlayback/docs/InstallArduino.gif differ diff --git a/third-party/TeensyVariablePlayback/docs/dependencies.png b/third-party/TeensyVariablePlayback/docs/dependencies.png new file mode 100644 index 0000000..94e3cd4 Binary files /dev/null and b/third-party/TeensyVariablePlayback/docs/dependencies.png differ diff --git a/third-party/TeensyVariablePlayback/examples/CMakeLists.txt b/third-party/TeensyVariablePlayback/examples/CMakeLists.txt new file mode 100644 index 0000000..b4d911d --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.5) +add_subdirectory(array) +add_subdirectory(sampleloader) +add_subdirectory(sd_play_all) +add_subdirectory(sd_raw) +add_subdirectory(sd_wav) diff --git a/third-party/TeensyVariablePlayback/examples/array/CMakeLists.txt b/third-party/TeensyVariablePlayback/examples/array/CMakeLists.txt new file mode 100644 index 0000000..101a642 --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/array/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.10) +project(array) +set(CMAKE_CXX_STANDARD 14) +teensy_include_directories(../../src) +teensy_add_executable(array array.ino) +teensy_target_link_libraries(array Audio teensy_variable_playback cores arm_math SD SPI Wire SerialFlash ) diff --git a/third-party/TeensyVariablePlayback/examples/array/array.ino b/third-party/TeensyVariablePlayback/examples/array/array.ino new file mode 100644 index 0000000..13ce0ef --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/array/array.ino @@ -0,0 +1,594 @@ +// Plays a RAW (16-bit signed) PCM audio file at slower or faster rate +// this example plays a sample stored in an array +#include +#include +#include + +// GUItool: begin automatically generated code +AudioPlayArrayResmp rraw_a1; //xy=321,513 +AudioOutputI2S i2s1; //xy=675,518 +AudioConnection patchCord1(rraw_a1, 0, i2s1, 0); +AudioConnection patchCord2(rraw_a1, 0, i2s1, 1); +AudioControlSGTL5000 sgtl5000_1; //xy=521,588 +// GUItool: end automatically generated code +#define A14 10 + +extern unsigned int kick_raw_len; +extern unsigned char kick_raw[]; +unsigned long lastSamplePlayed = 0; +const int analogInPin = A14; + +double getPlaybackRate(int16_t analog) { //analog: 0..1023 + return (analog - 512.0) / 512.0; +} + +void setup() { + analogReference(0); + pinMode(analogInPin, INPUT_DISABLE); // i.e. Analog + + Serial.begin(9600); + sgtl5000_1.enable(); + sgtl5000_1.volume(0.5f, 0.5f); + + rraw_a1.enableInterpolation(true); + int newsensorValue = analogRead(analogInPin); + rraw_a1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + AudioMemory(20); + Serial.println("setup done"); +} + +void loop() { + int newsensorValue = analogRead(analogInPin); + rraw_a1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 500) { + if (!rraw_a1.isPlaying()) { + rraw_a1.playRaw((int16_t *)kick_raw, kick_raw_len/2, 1); + lastSamplePlayed = currentMillis; + + Serial.print("Memory: "); + Serial.print(AudioMemoryUsage()); + Serial.print(","); + Serial.print(AudioMemoryUsageMax()); + Serial.println(); + } + } + delay(10); +} + +//created using linux command xxd -i kick.raw (44100Hz little-endian 16-bit/sample ) +unsigned char kick_raw[] = { + 0x99, 0x02, 0xd7, 0x02, 0xfa, 0x02, 0x5f, 0x03, 0xc1, 0x03, 0x2a, 0x04, + 0xad, 0x04, 0xa5, 0x05, 0x76, 0x06, 0x2f, 0x07, 0x9e, 0x07, 0xe2, 0x07, + 0x43, 0x08, 0x92, 0x08, 0xb2, 0x08, 0xe8, 0x08, 0x16, 0x09, 0xda, 0x08, + 0x51, 0x08, 0x01, 0x08, 0x25, 0x08, 0x70, 0x08, 0xc3, 0x08, 0x23, 0x09, + 0x95, 0x09, 0x19, 0x0a, 0x83, 0x0a, 0x7e, 0x0a, 0xd0, 0x0a, 0x65, 0x0b, + 0xf6, 0x0b, 0x89, 0x0c, 0xd1, 0x0c, 0xcf, 0x0c, 0x1a, 0x0d, 0xe5, 0x0d, + 0x5e, 0x0e, 0xbb, 0x0e, 0xec, 0x0e, 0xd9, 0x0e, 0x07, 0x0f, 0xc8, 0x0f, + 0x2a, 0x10, 0x04, 0x10, 0x28, 0x10, 0x54, 0x11, 0x8e, 0x13, 0x4b, 0x16, + 0x09, 0x19, 0x91, 0x1b, 0xf7, 0x1d, 0x55, 0x20, 0xd1, 0x22, 0xcb, 0x25, + 0x4d, 0x29, 0xa8, 0x2c, 0x7f, 0x2f, 0xda, 0x31, 0xac, 0x34, 0x0a, 0x3a, + 0x24, 0x47, 0x9d, 0x5b, 0xe9, 0x67, 0x29, 0x67, 0x24, 0x66, 0x26, 0x66, + 0xd2, 0x65, 0x9c, 0x65, 0x38, 0x65, 0x05, 0x65, 0x9f, 0x64, 0x64, 0x64, + 0x12, 0x64, 0xce, 0x63, 0x7c, 0x63, 0x32, 0x63, 0xe6, 0x62, 0x97, 0x62, + 0x49, 0x62, 0x01, 0x62, 0xb3, 0x61, 0x63, 0x61, 0x15, 0x61, 0xc4, 0x60, + 0x75, 0x60, 0x20, 0x60, 0xce, 0x5f, 0x7a, 0x5f, 0x28, 0x5f, 0xd5, 0x5e, + 0x81, 0x5e, 0x2d, 0x5e, 0xd3, 0x5d, 0x80, 0x5d, 0x2e, 0x5d, 0xe6, 0x5c, + 0x1a, 0x5c, 0x16, 0x5a, 0x01, 0x58, 0xb9, 0x56, 0x6d, 0x55, 0xf4, 0x53, + 0x49, 0x52, 0x83, 0x50, 0x87, 0x4e, 0x5f, 0x4c, 0x68, 0x4a, 0x5c, 0x48, + 0x62, 0x46, 0x5a, 0x44, 0xe2, 0x41, 0x08, 0x3f, 0x1c, 0x3c, 0x44, 0x39, + 0x35, 0x36, 0xcb, 0x32, 0xaf, 0x2f, 0xc8, 0x2c, 0xf8, 0x29, 0x55, 0x27, + 0x6a, 0x24, 0x0f, 0x21, 0x5e, 0x1d, 0xc3, 0x19, 0x7b, 0x16, 0x71, 0x13, + 0x6c, 0x10, 0x00, 0x0d, 0xd2, 0x08, 0x7f, 0x04, 0x7a, 0x01, 0x43, 0xff, + 0xb9, 0xfc, 0xfa, 0xf9, 0x3b, 0xf7, 0xcb, 0xf4, 0x2b, 0xf2, 0x02, 0xef, + 0x0c, 0xec, 0x3d, 0xe9, 0x21, 0xe6, 0xa6, 0xe2, 0x8a, 0xdf, 0x00, 0xdd, + 0xbc, 0xda, 0x9e, 0xd8, 0xc1, 0xd6, 0xd6, 0xd4, 0xd6, 0xd2, 0xad, 0xd0, + 0x5f, 0xce, 0xf0, 0xcb, 0xe9, 0xc9, 0x61, 0xc8, 0x75, 0xc7, 0x97, 0xc6, + 0x3e, 0xc5, 0x07, 0xc4, 0x8e, 0xc3, 0x18, 0xc3, 0x3a, 0xc2, 0x15, 0xc1, + 0x0e, 0xc0, 0xb3, 0xbf, 0xcf, 0xbf, 0xf8, 0xbf, 0xcc, 0xbf, 0x72, 0xbf, + 0x41, 0xbf, 0x2b, 0xbf, 0xe2, 0xbe, 0x99, 0xbe, 0x4e, 0xbe, 0x0e, 0xbe, + 0xcd, 0xbd, 0x7c, 0xbd, 0x8a, 0xbd, 0x88, 0xbd, 0x04, 0xbd, 0x0c, 0xbc, + 0xb3, 0xbb, 0xf6, 0xbb, 0xf1, 0xbb, 0x12, 0xbc, 0x6f, 0xbc, 0xcb, 0xbc, + 0xe4, 0xbc, 0x33, 0xbd, 0x1b, 0xbe, 0xac, 0xbe, 0x1e, 0xbf, 0x91, 0xbf, + 0x50, 0xc0, 0x40, 0xc1, 0x3d, 0xc2, 0x32, 0xc3, 0xdf, 0xc3, 0xad, 0xc4, + 0x77, 0xc5, 0xbe, 0xc6, 0xc7, 0xc8, 0x1d, 0xcb, 0x0e, 0xcd, 0x83, 0xce, + 0xf1, 0xcf, 0xb4, 0xd1, 0x7d, 0xd3, 0x86, 0xd5, 0x89, 0xd7, 0xd2, 0xd9, + 0x34, 0xdc, 0x28, 0xde, 0x23, 0xe0, 0x33, 0xe2, 0x0a, 0xe4, 0x59, 0xe5, + 0xfc, 0xe6, 0x98, 0xe9, 0x30, 0xec, 0x91, 0xee, 0xc2, 0xf0, 0x0d, 0xf3, + 0x35, 0xf5, 0xf3, 0xf6, 0xc4, 0xf8, 0xcb, 0xfa, 0xef, 0xfc, 0x65, 0xff, + 0x05, 0x02, 0x7c, 0x04, 0xde, 0x06, 0x75, 0x09, 0x2b, 0x0c, 0x9b, 0x0e, + 0xf3, 0x10, 0xb3, 0x13, 0x3a, 0x16, 0xeb, 0x18, 0x55, 0x1c, 0xad, 0x1f, + 0xa8, 0x22, 0x54, 0x25, 0xae, 0x27, 0x33, 0x2a, 0x16, 0x2d, 0x36, 0x30, + 0x84, 0x33, 0x94, 0x36, 0xbd, 0x38, 0xa2, 0x3a, 0x7d, 0x3c, 0x06, 0x3e, + 0x24, 0x3f, 0x27, 0x40, 0x7c, 0x41, 0xef, 0x42, 0x14, 0x44, 0xeb, 0x44, + 0x06, 0x46, 0x53, 0x47, 0x47, 0x48, 0x9b, 0x48, 0xaf, 0x48, 0xd7, 0x48, + 0x4c, 0x49, 0xa0, 0x49, 0xbe, 0x49, 0xd4, 0x49, 0xfa, 0x49, 0x5e, 0x4a, + 0xcc, 0x4a, 0x14, 0x4b, 0xfe, 0x4a, 0x22, 0x4b, 0x10, 0x4c, 0x0c, 0x4d, + 0xb2, 0x4d, 0x4c, 0x4e, 0x3e, 0x4e, 0x77, 0x4d, 0x98, 0x4c, 0xf6, 0x4b, + 0x67, 0x4b, 0xf0, 0x4a, 0x2a, 0x4a, 0xea, 0x48, 0x06, 0x48, 0x47, 0x47, + 0xb2, 0x46, 0xda, 0x45, 0xad, 0x44, 0x5c, 0x43, 0x43, 0x42, 0x9e, 0x41, + 0x0a, 0x41, 0x49, 0x40, 0xa6, 0x3f, 0x9d, 0x3e, 0x3c, 0x3d, 0xc6, 0x3b, + 0xf6, 0x39, 0x87, 0x37, 0xf6, 0x34, 0x87, 0x32, 0x2b, 0x30, 0x6f, 0x2d, + 0xfa, 0x2a, 0x3d, 0x29, 0x48, 0x27, 0xc2, 0x24, 0x49, 0x22, 0xca, 0x1f, + 0xa0, 0x1c, 0x7c, 0x19, 0x06, 0x17, 0xbf, 0x14, 0x9f, 0x12, 0x96, 0x10, + 0xf9, 0x0d, 0x3e, 0x0b, 0xe8, 0x08, 0x5c, 0x06, 0xe7, 0x02, 0x6e, 0xff, + 0xca, 0xfc, 0x5b, 0xfa, 0xa0, 0xf7, 0xe9, 0xf4, 0x9c, 0xf2, 0x66, 0xf0, + 0xaf, 0xed, 0xfd, 0xea, 0xcc, 0xe8, 0x6e, 0xe6, 0x82, 0xe3, 0x97, 0xe0, + 0xed, 0xdd, 0x62, 0xdb, 0x7b, 0xd8, 0xd3, 0xd5, 0x5f, 0xd3, 0x1a, 0xd1, + 0x44, 0xcf, 0xeb, 0xcd, 0x89, 0xcc, 0xca, 0xca, 0x4d, 0xc9, 0x35, 0xc8, + 0x53, 0xc7, 0x0c, 0xc6, 0x06, 0xc4, 0xca, 0xc1, 0x09, 0xc0, 0x9c, 0xbe, + 0xa8, 0xbd, 0xfd, 0xbc, 0xf2, 0xbb, 0x9b, 0xba, 0x20, 0xb9, 0xe4, 0xb7, + 0xc1, 0xb6, 0xcd, 0xb5, 0x12, 0xb5, 0x55, 0xb4, 0xd1, 0xb3, 0x86, 0xb3, + 0x19, 0xb3, 0xe8, 0xb2, 0xd7, 0xb2, 0x72, 0xb2, 0x27, 0xb2, 0xb7, 0xb1, + 0x67, 0xb1, 0x65, 0xb1, 0xae, 0xb1, 0x6b, 0xb1, 0xf2, 0xb0, 0xeb, 0xb0, + 0x0f, 0xb1, 0xfe, 0xb0, 0xeb, 0xb0, 0xcf, 0xb0, 0x94, 0xb0, 0x3e, 0xb0, + 0x29, 0xb0, 0x56, 0xb0, 0x0c, 0xb0, 0xb7, 0xaf, 0xfb, 0xaf, 0x37, 0xb0, + 0x96, 0xb0, 0x42, 0xb1, 0xe8, 0xb1, 0xb5, 0xb2, 0xc5, 0xb3, 0x93, 0xb4, + 0x93, 0xb4, 0xee, 0xb4, 0x59, 0xb6, 0xca, 0xb7, 0x87, 0xb8, 0x6f, 0xb8, + 0x33, 0xb8, 0xaf, 0xb8, 0x4a, 0xb9, 0x9d, 0xb9, 0xf2, 0xb9, 0x48, 0xba, + 0xd0, 0xba, 0xe5, 0xbb, 0x4e, 0xbd, 0xaf, 0xbe, 0xe9, 0xbf, 0xba, 0xc1, + 0xc2, 0xc3, 0x73, 0xc5, 0xa6, 0xc6, 0x6a, 0xc7, 0x83, 0xc8, 0x42, 0xca, + 0xc8, 0xcb, 0x34, 0xcd, 0x94, 0xce, 0xcc, 0xcf, 0x31, 0xd1, 0x27, 0xd3, + 0x8c, 0xd5, 0x61, 0xd7, 0x78, 0xd9, 0x3b, 0xdc, 0x40, 0xdf, 0xdd, 0xe1, + 0x0c, 0xe4, 0xe4, 0xe5, 0xd0, 0xe7, 0x65, 0xea, 0xc9, 0xec, 0xd7, 0xee, + 0xfc, 0xf0, 0x7c, 0xf3, 0xf6, 0xf5, 0x09, 0xf8, 0xde, 0xf9, 0xca, 0xfb, + 0xac, 0xfd, 0xc3, 0xff, 0x33, 0x02, 0xb1, 0x04, 0x24, 0x07, 0x57, 0x09, + 0x5f, 0x0b, 0xe6, 0x0d, 0xd1, 0x10, 0x6d, 0x13, 0x8f, 0x15, 0xfb, 0x17, + 0x43, 0x1a, 0x8e, 0x1c, 0x1a, 0x1f, 0x69, 0x21, 0x80, 0x23, 0x74, 0x25, + 0x62, 0x27, 0x07, 0x29, 0xa1, 0x2a, 0xa5, 0x2c, 0xdf, 0x2e, 0x57, 0x31, + 0xff, 0x33, 0xd1, 0x36, 0x6e, 0x39, 0x8a, 0x3b, 0x58, 0x3d, 0x32, 0x3f, + 0xc8, 0x40, 0x1b, 0x42, 0x22, 0x43, 0x1a, 0x44, 0x25, 0x45, 0xe5, 0x45, + 0x43, 0x46, 0x9b, 0x46, 0x6a, 0x47, 0x6f, 0x48, 0x69, 0x49, 0x6f, 0x4a, + 0xc7, 0x4b, 0x0e, 0x4d, 0x03, 0x4e, 0x78, 0x4e, 0xdf, 0x4e, 0x0b, 0x4f, + 0xea, 0x4e, 0xcb, 0x4e, 0x1b, 0x4f, 0x6e, 0x4f, 0xc3, 0x4f, 0xdc, 0x4f, + 0xcb, 0x4f, 0xd2, 0x4f, 0x16, 0x50, 0x24, 0x50, 0xf2, 0x4f, 0x00, 0x50, + 0x37, 0x50, 0x4e, 0x50, 0x5e, 0x50, 0x7c, 0x50, 0xab, 0x50, 0x69, 0x50, + 0xad, 0x4f, 0xa3, 0x4e, 0xe6, 0x4d, 0x42, 0x4d, 0xdc, 0x4c, 0x7c, 0x4c, + 0xbe, 0x4b, 0x08, 0x4b, 0x7b, 0x4a, 0xe4, 0x49, 0x14, 0x49, 0x07, 0x48, + 0x98, 0x46, 0x2f, 0x45, 0x16, 0x44, 0x23, 0x43, 0x55, 0x42, 0xac, 0x41, + 0x06, 0x41, 0x4b, 0x40, 0x8f, 0x3f, 0xde, 0x3e, 0xe1, 0x3d, 0x75, 0x3c, + 0xc0, 0x3a, 0xe4, 0x38, 0x83, 0x37, 0x9a, 0x36, 0xe5, 0x35, 0xc0, 0x34, + 0xf9, 0x32, 0xe1, 0x30, 0xfa, 0x2e, 0xd4, 0x2c, 0x4d, 0x2a, 0xed, 0x27, + 0xb9, 0x25, 0xb2, 0x23, 0x7d, 0x21, 0xfd, 0x1e, 0x89, 0x1c, 0x38, 0x1a, + 0xe2, 0x17, 0x67, 0x15, 0xf3, 0x12, 0xb3, 0x10, 0x9e, 0x0e, 0x79, 0x0c, + 0xea, 0x09, 0x54, 0x07, 0x26, 0x05, 0x0a, 0x03, 0xd7, 0x00, 0x98, 0xfe, + 0x41, 0xfc, 0x8d, 0xf9, 0x3c, 0xf7, 0x4f, 0xf5, 0x73, 0xf3, 0x7b, 0xf1, + 0x68, 0xef, 0x6f, 0xed, 0x7a, 0xeb, 0x87, 0xe9, 0x48, 0xe7, 0xc6, 0xe4, + 0x65, 0xe2, 0xf6, 0xdf, 0x86, 0xdd, 0x9f, 0xdb, 0x1b, 0xda, 0xa6, 0xd8, + 0xce, 0xd6, 0xe4, 0xd4, 0xe3, 0xd2, 0x84, 0xd0, 0xec, 0xcd, 0x08, 0xcc, + 0x89, 0xca, 0x1b, 0xc9, 0xe2, 0xc7, 0x9d, 0xc6, 0xe5, 0xc4, 0x79, 0xc3, + 0x6d, 0xc2, 0xe3, 0xc0, 0x3c, 0xbf, 0xd3, 0xbd, 0x41, 0xbc, 0xd2, 0xba, + 0x6a, 0xb9, 0xa1, 0xb7, 0xa9, 0xb5, 0x47, 0xb4, 0x91, 0xb3, 0xd5, 0xb2, + 0xb7, 0xb1, 0x51, 0xb0, 0x14, 0xaf, 0xf5, 0xad, 0x95, 0xac, 0x34, 0xab, + 0x05, 0xaa, 0xe1, 0xa8, 0xb3, 0xa7, 0xd9, 0xa6, 0x25, 0xa6, 0x6e, 0xa5, + 0x2b, 0xa5, 0x7b, 0xa5, 0x9a, 0xa5, 0x88, 0xa5, 0xc3, 0xa5, 0xe7, 0xa5, + 0xaf, 0xa5, 0x8b, 0xa5, 0x80, 0xa5, 0x65, 0xa5, 0x8c, 0xa5, 0x7e, 0xa5, + 0x22, 0xa5, 0x40, 0xa5, 0xed, 0xa5, 0x27, 0xa6, 0x2b, 0xa6, 0x1c, 0xa6, + 0xe5, 0xa5, 0x7b, 0xa5, 0x45, 0xa5, 0x37, 0xa5, 0x04, 0xa5, 0x91, 0xa4, + 0x8d, 0xa4, 0x2d, 0xa5, 0x9f, 0xa5, 0xf6, 0xa5, 0x7e, 0xa6, 0x34, 0xa7, + 0x14, 0xa8, 0x7e, 0xa8, 0x87, 0xa8, 0xc4, 0xa8, 0x51, 0xa9, 0xec, 0xa9, + 0x74, 0xaa, 0xf7, 0xaa, 0x40, 0xab, 0xd9, 0xab, 0xca, 0xac, 0x6b, 0xad, + 0xb3, 0xad, 0x08, 0xae, 0x10, 0xaf, 0x2c, 0xb0, 0xcb, 0xb0, 0x23, 0xb1, + 0xac, 0xb1, 0x0e, 0xb2, 0x42, 0xb2, 0xd7, 0xb2, 0xef, 0xb3, 0x21, 0xb5, + 0x30, 0xb6, 0xe9, 0xb6, 0x54, 0xb7, 0xf0, 0xb7, 0x9e, 0xb8, 0x2e, 0xb9, + 0x03, 0xba, 0x55, 0xbb, 0xdf, 0xbc, 0x5f, 0xbe, 0xb8, 0xbf, 0x01, 0xc1, + 0x83, 0xc2, 0x0c, 0xc4, 0x65, 0xc5, 0x7e, 0xc6, 0x86, 0xc7, 0xba, 0xc8, + 0x11, 0xca, 0x66, 0xcb, 0x28, 0xcd, 0x4d, 0xcf, 0x60, 0xd1, 0x69, 0xd3, + 0x7b, 0xd5, 0x5f, 0xd7, 0xe3, 0xd8, 0xca, 0xda, 0xda, 0xdc, 0xda, 0xde, + 0xab, 0xe0, 0x59, 0xe2, 0x3b, 0xe4, 0x21, 0xe6, 0xfc, 0xe7, 0xcb, 0xe9, + 0xbe, 0xeb, 0x9c, 0xed, 0x47, 0xef, 0x0b, 0xf1, 0xd3, 0xf2, 0xbc, 0xf4, + 0x9c, 0xf6, 0x67, 0xf8, 0x2a, 0xfa, 0xc1, 0xfb, 0x7f, 0xfd, 0x41, 0xff, + 0x12, 0x01, 0xd2, 0x02, 0xfc, 0x04, 0xe8, 0x06, 0x9a, 0x08, 0x59, 0x0a, + 0x48, 0x0c, 0x36, 0x0e, 0x37, 0x10, 0x36, 0x12, 0x59, 0x14, 0x62, 0x16, + 0x86, 0x18, 0xb9, 0x1a, 0xc2, 0x1c, 0xcd, 0x1e, 0xf1, 0x20, 0x27, 0x23, + 0x7a, 0x25, 0xf9, 0x27, 0x2a, 0x2a, 0x1f, 0x2c, 0xf8, 0x2d, 0xa3, 0x2f, + 0x23, 0x31, 0xf4, 0x32, 0x2c, 0x35, 0x40, 0x37, 0x23, 0x39, 0xfe, 0x3a, + 0x11, 0x3d, 0x2c, 0x3f, 0xe8, 0x40, 0x8c, 0x42, 0x55, 0x44, 0x37, 0x46, + 0x99, 0x47, 0xcb, 0x48, 0x12, 0x4a, 0x60, 0x4b, 0x86, 0x4c, 0x9b, 0x4d, + 0xc8, 0x4e, 0xec, 0x4f, 0xe3, 0x50, 0x8a, 0x51, 0x23, 0x52, 0xd8, 0x52, + 0x68, 0x53, 0x9b, 0x53, 0xb1, 0x53, 0x11, 0x54, 0x94, 0x54, 0xf7, 0x54, + 0x4f, 0x55, 0xa4, 0x55, 0x03, 0x56, 0x51, 0x56, 0x92, 0x56, 0xfa, 0x56, + 0x59, 0x57, 0xad, 0x57, 0xcd, 0x57, 0xc5, 0x57, 0xa8, 0x57, 0x64, 0x57, + 0x49, 0x57, 0x63, 0x57, 0x64, 0x57, 0x40, 0x57, 0xf6, 0x56, 0xfc, 0x56, + 0x36, 0x57, 0x3b, 0x57, 0x1e, 0x57, 0x1c, 0x57, 0x03, 0x57, 0xee, 0x56, + 0xa5, 0x56, 0x80, 0x56, 0xd4, 0x56, 0xe4, 0x56, 0x92, 0x56, 0xf0, 0x55, + 0x02, 0x55, 0xab, 0x53, 0xb5, 0x52, 0x51, 0x52, 0x08, 0x52, 0x80, 0x51, + 0xb4, 0x50, 0xde, 0x4f, 0x27, 0x4f, 0x63, 0x4e, 0x58, 0x4d, 0x72, 0x4c, + 0x82, 0x4b, 0x81, 0x4a, 0x87, 0x49, 0xb4, 0x48, 0xb1, 0x47, 0x99, 0x46, + 0xb4, 0x45, 0x34, 0x45, 0xb8, 0x44, 0x2f, 0x44, 0x7f, 0x43, 0xa0, 0x42, + 0xcb, 0x41, 0xd1, 0x40, 0xeb, 0x3f, 0x28, 0x3f, 0x3d, 0x3e, 0x09, 0x3d, + 0x9d, 0x3b, 0x40, 0x3a, 0x1c, 0x39, 0xeb, 0x37, 0xd1, 0x36, 0xb3, 0x35, + 0x8b, 0x34, 0x0b, 0x33, 0x51, 0x31, 0xfb, 0x2f, 0xb9, 0x2e, 0x54, 0x2d, + 0xaf, 0x2b, 0xdf, 0x29, 0xf1, 0x27, 0x3a, 0x26, 0x6f, 0x24, 0x56, 0x22, + 0x20, 0x20, 0x0a, 0x1e, 0x3b, 0x1c, 0x55, 0x1a, 0x6c, 0x18, 0xaa, 0x16, + 0xef, 0x14, 0x0a, 0x13, 0x17, 0x11, 0x1c, 0x0f, 0x22, 0x0d, 0x46, 0x0b, + 0x53, 0x09, 0x46, 0x07, 0x46, 0x05, 0x4d, 0x03, 0x1a, 0x01, 0xd3, 0xfe, + 0x94, 0xfc, 0x8c, 0xfa, 0x8f, 0xf8, 0xc1, 0xf6, 0x27, 0xf5, 0x8f, 0xf3, + 0xf2, 0xf1, 0x74, 0xf0, 0xfa, 0xee, 0x4d, 0xed, 0x9e, 0xeb, 0xa2, 0xe9, + 0x73, 0xe7, 0xa9, 0xe5, 0x2d, 0xe4, 0xa3, 0xe2, 0xf9, 0xe0, 0x50, 0xdf, + 0xb9, 0xdd, 0x34, 0xdc, 0xad, 0xda, 0x0b, 0xd9, 0x77, 0xd7, 0xb9, 0xd5, + 0x37, 0xd4, 0xff, 0xd2, 0x8a, 0xd1, 0x14, 0xd0, 0xba, 0xce, 0x7d, 0xcd, + 0x2c, 0xcc, 0xa1, 0xca, 0x22, 0xc9, 0xa9, 0xc7, 0x0e, 0xc6, 0x66, 0xc4, + 0xfc, 0xc2, 0xa5, 0xc1, 0x4a, 0xc0, 0xff, 0xbe, 0xf7, 0xbd, 0x0e, 0xbd, + 0x1d, 0xbc, 0x16, 0xbb, 0xad, 0xb9, 0x44, 0xb8, 0xd7, 0xb6, 0x9e, 0xb5, + 0x9f, 0xb4, 0x97, 0xb3, 0x72, 0xb2, 0x5f, 0xb1, 0x67, 0xb0, 0x89, 0xaf, + 0x9d, 0xae, 0xbe, 0xad, 0x08, 0xad, 0x5d, 0xac, 0x8b, 0xab, 0xad, 0xaa, + 0xe4, 0xa9, 0x59, 0xa9, 0xc4, 0xa8, 0x02, 0xa8, 0x4d, 0xa7, 0xc2, 0xa6, + 0x4a, 0xa6, 0x09, 0xa6, 0xd2, 0xa5, 0x50, 0xa5, 0xec, 0xa4, 0xc2, 0xa4, + 0xd9, 0xa4, 0xbd, 0xa4, 0x97, 0xa4, 0xa5, 0xa4, 0xbf, 0xa4, 0xb4, 0xa4, + 0x8f, 0xa4, 0x31, 0xa4, 0x39, 0xa4, 0x7d, 0xa4, 0xab, 0xa4, 0xc7, 0xa4, + 0xb3, 0xa4, 0xab, 0xa4, 0xca, 0xa4, 0x05, 0xa5, 0x1e, 0xa5, 0x2a, 0xa5, + 0x2c, 0xa5, 0x18, 0xa5, 0x01, 0xa5, 0x33, 0xa5, 0x8c, 0xa5, 0xb2, 0xa5, + 0x81, 0xa5, 0x5c, 0xa5, 0x6e, 0xa5, 0x79, 0xa5, 0x4e, 0xa5, 0x17, 0xa5, + 0xff, 0xa4, 0x1c, 0xa5, 0x45, 0xa5, 0x8a, 0xa5, 0xbf, 0xa5, 0xdb, 0xa5, + 0x41, 0xa6, 0xfb, 0xa6, 0xc6, 0xa7, 0x86, 0xa8, 0x29, 0xa9, 0x97, 0xa9, + 0x27, 0xaa, 0xd7, 0xaa, 0x6d, 0xab, 0xf4, 0xab, 0x34, 0xac, 0x69, 0xac, + 0xc6, 0xac, 0x37, 0xad, 0xaa, 0xad, 0x34, 0xae, 0xd3, 0xae, 0x81, 0xaf, + 0x16, 0xb0, 0x72, 0xb0, 0xc8, 0xb0, 0x36, 0xb1, 0x91, 0xb1, 0xe0, 0xb1, + 0x3b, 0xb2, 0x8e, 0xb2, 0xe0, 0xb2, 0x2a, 0xb3, 0xab, 0xb3, 0x3a, 0xb4, + 0xf1, 0xb4, 0xc0, 0xb5, 0xae, 0xb6, 0x91, 0xb7, 0x82, 0xb8, 0x98, 0xb9, + 0x8f, 0xba, 0x88, 0xbb, 0x65, 0xbc, 0x20, 0xbd, 0xcb, 0xbd, 0xaf, 0xbe, + 0x94, 0xbf, 0x84, 0xc0, 0x85, 0xc1, 0x7b, 0xc2, 0x67, 0xc3, 0x66, 0xc4, + 0x7f, 0xc5, 0x89, 0xc6, 0x6b, 0xc7, 0x38, 0xc8, 0x29, 0xc9, 0x4a, 0xca, + 0x82, 0xcb, 0xc1, 0xcc, 0x12, 0xce, 0x5e, 0xcf, 0xb0, 0xd0, 0x25, 0xd2, + 0x66, 0xd3, 0xde, 0xd4, 0x6c, 0xd6, 0x28, 0xd8, 0xd7, 0xd9, 0x80, 0xdb, + 0xf7, 0xdc, 0x6f, 0xde, 0xd0, 0xdf, 0x22, 0xe1, 0x7a, 0xe2, 0xe5, 0xe3, + 0x7a, 0xe5, 0xea, 0xe6, 0x51, 0xe8, 0xeb, 0xe9, 0x70, 0xeb, 0xb3, 0xec, + 0x01, 0xee, 0x60, 0xef, 0xcb, 0xf0, 0x1d, 0xf2, 0x7b, 0xf3, 0xcf, 0xf4, + 0x39, 0xf6, 0xc8, 0xf7, 0x82, 0xf9, 0x4a, 0xfb, 0xf2, 0xfc, 0x8c, 0xfe, + 0x01, 0x00, 0x68, 0x01, 0x15, 0x03, 0xe6, 0x04, 0xbc, 0x06, 0x42, 0x08, + 0xbb, 0x09, 0x2b, 0x0b, 0xc7, 0x0c, 0x35, 0x0e, 0x94, 0x0f, 0xf2, 0x10, + 0x59, 0x12, 0xbc, 0x13, 0x34, 0x15, 0xac, 0x16, 0x1c, 0x18, 0x79, 0x19, + 0xdc, 0x1a, 0x6d, 0x1c, 0x21, 0x1e, 0xca, 0x1f, 0x70, 0x21, 0x02, 0x23, + 0x6c, 0x24, 0x9e, 0x25, 0x45, 0x27, 0x02, 0x29, 0x95, 0x2a, 0xff, 0x2b, + 0x72, 0x2d, 0xe8, 0x2e, 0x48, 0x30, 0x7c, 0x31, 0xd2, 0x32, 0x3d, 0x34, + 0xac, 0x35, 0x26, 0x37, 0xbc, 0x38, 0x4c, 0x3a, 0x90, 0x3b, 0xef, 0x3c, + 0x61, 0x3e, 0xe8, 0x3f, 0x59, 0x41, 0xab, 0x42, 0xf7, 0x43, 0x2d, 0x45, + 0x6c, 0x46, 0x78, 0x47, 0xb4, 0x48, 0x2e, 0x4a, 0x8e, 0x4b, 0xd7, 0x4c, + 0xf4, 0x4d, 0xee, 0x4e, 0xcb, 0x4f, 0xc3, 0x50, 0xc2, 0x51, 0xac, 0x52, + 0x61, 0x53, 0xf3, 0x53, 0xac, 0x54, 0x5f, 0x55, 0xf4, 0x55, 0x7f, 0x56, + 0x04, 0x57, 0x9c, 0x57, 0x1f, 0x58, 0x7c, 0x58, 0xbc, 0x58, 0x0b, 0x59, + 0x71, 0x59, 0xc1, 0x59, 0x0b, 0x5a, 0x3e, 0x5a, 0x8b, 0x5a, 0xac, 0x5a, + 0xa9, 0x5a, 0x8a, 0x5a, 0x6c, 0x5a, 0x4c, 0x5a, 0x39, 0x5a, 0x32, 0x5a, + 0x40, 0x5a, 0x33, 0x5a, 0x44, 0x5a, 0x58, 0x5a, 0x79, 0x5a, 0x7a, 0x5a, + 0x69, 0x5a, 0x49, 0x5a, 0x54, 0x5a, 0x78, 0x5a, 0x72, 0x5a, 0x5f, 0x5a, + 0x31, 0x5a, 0x11, 0x5a, 0xf9, 0x59, 0xea, 0x59, 0xd1, 0x59, 0xa1, 0x59, + 0x48, 0x59, 0xf0, 0x58, 0xa2, 0x58, 0x6e, 0x58, 0x60, 0x58, 0x46, 0x58, + 0x3f, 0x58, 0x47, 0x58, 0x40, 0x58, 0x08, 0x58, 0x9c, 0x57, 0x11, 0x57, + 0x83, 0x56, 0xd7, 0x55, 0x42, 0x55, 0xab, 0x54, 0x06, 0x54, 0x63, 0x53, + 0xa6, 0x52, 0xf0, 0x51, 0x55, 0x51, 0xbc, 0x50, 0x1e, 0x50, 0x8e, 0x4f, + 0xf3, 0x4e, 0x34, 0x4e, 0x6b, 0x4d, 0xc9, 0x4c, 0x30, 0x4c, 0x7d, 0x4b, + 0xd8, 0x4a, 0x49, 0x4a, 0xad, 0x49, 0x11, 0x49, 0x6c, 0x48, 0xa4, 0x47, + 0xec, 0x46, 0x6c, 0x46, 0xde, 0x45, 0x5d, 0x45, 0xbc, 0x44, 0xf1, 0x43, + 0x34, 0x43, 0x8c, 0x42, 0xf8, 0x41, 0x47, 0x41, 0x6a, 0x40, 0x72, 0x3f, + 0x8b, 0x3e, 0xb3, 0x3d, 0xf2, 0x3c, 0x2f, 0x3c, 0x5c, 0x3b, 0x96, 0x3a, + 0xbc, 0x39, 0xb2, 0x38, 0x91, 0x37, 0x8c, 0x36, 0x75, 0x35, 0x63, 0x34, + 0x5e, 0x33, 0x63, 0x32, 0x4b, 0x31, 0x3c, 0x30, 0x1e, 0x2f, 0x07, 0x2e, + 0xd0, 0x2c, 0xb2, 0x2b, 0x84, 0x2a, 0x4d, 0x29, 0xfc, 0x27, 0xa5, 0x26, + 0x2f, 0x25, 0x95, 0x23, 0x1f, 0x22, 0xad, 0x20, 0x3a, 0x1f, 0x9e, 0x1d, + 0x10, 0x1c, 0x6e, 0x1a, 0xe3, 0x18, 0x56, 0x17, 0xdb, 0x15, 0x58, 0x14, + 0xba, 0x12, 0x2a, 0x11, 0x8b, 0x0f, 0xf4, 0x0d, 0x5b, 0x0c, 0xd3, 0x0a, + 0x5f, 0x09, 0xe5, 0x07, 0x4a, 0x06, 0xc0, 0x04, 0x3e, 0x03, 0xb6, 0x01, + 0x37, 0x00, 0xca, 0xfe, 0x74, 0xfd, 0x00, 0xfc, 0xa5, 0xfa, 0x4a, 0xf9, + 0xd1, 0xf7, 0x7e, 0xf6, 0x1c, 0xf5, 0x9d, 0xf3, 0x4f, 0xf2, 0x0e, 0xf1, + 0xc0, 0xef, 0x3a, 0xee, 0xd8, 0xec, 0x69, 0xeb, 0x0c, 0xea, 0xad, 0xe8, + 0x56, 0xe7, 0xf8, 0xe5, 0xbe, 0xe4, 0x98, 0xe3, 0x61, 0xe2, 0x03, 0xe1, + 0x99, 0xdf, 0x4d, 0xde, 0x0e, 0xdd, 0xde, 0xdb, 0xad, 0xda, 0x84, 0xd9, + 0x62, 0xd8, 0x32, 0xd7, 0x01, 0xd6, 0xb7, 0xd4, 0x87, 0xd3, 0x97, 0xd2, + 0x89, 0xd1, 0x89, 0xd0, 0x6e, 0xcf, 0x65, 0xce, 0x5d, 0xcd, 0x44, 0xcc, + 0x13, 0xcb, 0xf2, 0xc9, 0xd3, 0xc8, 0xad, 0xc7, 0x9b, 0xc6, 0x94, 0xc5, + 0x8e, 0xc4, 0x7b, 0xc3, 0x92, 0xc2, 0xad, 0xc1, 0xb2, 0xc0, 0xb9, 0xbf, + 0xb3, 0xbe, 0xc0, 0xbd, 0xd5, 0xbc, 0xf2, 0xbb, 0xe1, 0xba, 0xc7, 0xb9, + 0xc7, 0xb8, 0xe8, 0xb7, 0x09, 0xb7, 0x2c, 0xb6, 0x66, 0xb5, 0xb1, 0xb4, + 0xf6, 0xb3, 0x32, 0xb3, 0x53, 0xb2, 0x92, 0xb1, 0xdb, 0xb0, 0x0d, 0xb0, + 0x46, 0xaf, 0x62, 0xae, 0x98, 0xad, 0xd1, 0xac, 0x3f, 0xac, 0xb0, 0xab, + 0x34, 0xab, 0xb1, 0xaa, 0x45, 0xaa, 0xda, 0xa9, 0x6a, 0xa9, 0xf1, 0xa8, + 0x7d, 0xa8, 0x04, 0xa8, 0xbb, 0xa7, 0x80, 0xa7, 0x41, 0xa7, 0x02, 0xa7, + 0xb6, 0xa6, 0x68, 0xa6, 0x3b, 0xa6, 0x1c, 0xa6, 0x0d, 0xa6, 0xfc, 0xa5, + 0xd4, 0xa5, 0xa6, 0xa5, 0x81, 0xa5, 0x76, 0xa5, 0x61, 0xa5, 0x54, 0xa5, + 0x48, 0xa5, 0x47, 0xa5, 0x4b, 0xa5, 0x49, 0xa5, 0x38, 0xa5, 0x4b, 0xa5, + 0x6c, 0xa5, 0xa3, 0xa5, 0xda, 0xa5, 0xfe, 0xa5, 0x21, 0xa6, 0x4a, 0xa6, + 0x8a, 0xa6, 0xb4, 0xa6, 0xe0, 0xa6, 0xf3, 0xa6, 0x1b, 0xa7, 0x17, 0xa7, + 0x40, 0xa7, 0x8e, 0xa7, 0xcd, 0xa7, 0x06, 0xa8, 0x3e, 0xa8, 0x86, 0xa8, + 0xbd, 0xa8, 0xde, 0xa8, 0xf6, 0xa8, 0x1c, 0xa9, 0x49, 0xa9, 0x5c, 0xa9, + 0x79, 0xa9, 0x93, 0xa9, 0xab, 0xa9, 0xe6, 0xa9, 0x2c, 0xaa, 0x82, 0xaa, + 0xbc, 0xaa, 0xec, 0xaa, 0x32, 0xab, 0x69, 0xab, 0xa7, 0xab, 0xde, 0xab, + 0x19, 0xac, 0x53, 0xac, 0xbb, 0xac, 0x14, 0xad, 0x8a, 0xad, 0xeb, 0xad, + 0x6c, 0xae, 0xe1, 0xae, 0x62, 0xaf, 0xd9, 0xaf, 0x58, 0xb0, 0xc0, 0xb0, + 0x36, 0xb1, 0x99, 0xb1, 0x11, 0xb2, 0x71, 0xb2, 0xdc, 0xb2, 0x58, 0xb3, + 0xbb, 0xb3, 0x37, 0xb4, 0xb6, 0xb4, 0x46, 0xb5, 0xca, 0xb5, 0x50, 0xb6, + 0xd9, 0xb6, 0x6c, 0xb7, 0x03, 0xb8, 0x7e, 0xb8, 0xf0, 0xb8, 0x64, 0xb9, + 0xcf, 0xb9, 0x47, 0xba, 0xd3, 0xba, 0x60, 0xbb, 0xe8, 0xbb, 0x70, 0xbc, + 0xf3, 0xbc, 0x82, 0xbd, 0x05, 0xbe, 0xa1, 0xbe, 0x2a, 0xbf, 0xae, 0xbf, + 0x25, 0xc0, 0xac, 0xc0, 0x52, 0xc1, 0xde, 0xc1, 0x75, 0xc2, 0x11, 0xc3, + 0xb5, 0xc3, 0x42, 0xc4, 0xc5, 0xc4, 0x6d, 0xc5, 0x0b, 0xc6, 0xb2, 0xc6, + 0x4b, 0xc7, 0xf6, 0xc7, 0x9b, 0xc8, 0x4f, 0xc9, 0x17, 0xca, 0xf3, 0xca, + 0xc6, 0xcb, 0x9a, 0xcc, 0x7b, 0xcd, 0x54, 0xce, 0x32, 0xcf, 0x09, 0xd0, + 0xd7, 0xd0, 0xc9, 0xd1, 0xc1, 0xd2, 0xb8, 0xd3, 0xb6, 0xd4, 0xae, 0xd5, + 0xbc, 0xd6, 0xca, 0xd7, 0xd2, 0xd8, 0xca, 0xd9, 0xbd, 0xda, 0xc8, 0xdb, + 0xd8, 0xdc, 0xf9, 0xdd, 0x08, 0xdf, 0x1e, 0xe0, 0x39, 0xe1, 0x4e, 0xe2, + 0x60, 0xe3, 0x7a, 0xe4, 0x96, 0xe5, 0xc1, 0xe6, 0xde, 0xe7, 0x0e, 0xe9, + 0x2a, 0xea, 0x42, 0xeb, 0x7a, 0xec, 0x9f, 0xed, 0xbb, 0xee, 0xd6, 0xef, + 0xef, 0xf0, 0x0e, 0xf2, 0x30, 0xf3, 0x55, 0xf4, 0x68, 0xf5, 0x7e, 0xf6, + 0xa4, 0xf7, 0xc0, 0xf8, 0xea, 0xf9, 0x10, 0xfb, 0x41, 0xfc, 0x7d, 0xfd, + 0xad, 0xfe, 0xe3, 0xff, 0x10, 0x01, 0x27, 0x02, 0x58, 0x03, 0x74, 0x04, + 0xa4, 0x05, 0xd5, 0x06, 0x0b, 0x08, 0x36, 0x09, 0x5c, 0x0a, 0x76, 0x0b, + 0x9a, 0x0c, 0xc1, 0x0d, 0xd8, 0x0e, 0xf5, 0x0f, 0x15, 0x11, 0x3f, 0x12, + 0x70, 0x13, 0x8e, 0x14, 0xcc, 0x15, 0xf2, 0x16, 0x31, 0x18, 0x4b, 0x19, + 0x82, 0x1a, 0xa1, 0x1b, 0xbc, 0x1c, 0xde, 0x1d, 0xe9, 0x1e, 0x13, 0x20, + 0x33, 0x21, 0x6c, 0x22, 0x80, 0x23, 0xa7, 0x24, 0xbc, 0x25, 0xde, 0x26, + 0xe7, 0x27, 0x07, 0x29, 0x28, 0x2a, 0x36, 0x2b, 0x4d, 0x2c, 0x71, 0x2d, + 0x91, 0x2e, 0xbe, 0x2f, 0xd6, 0x30, 0xfb, 0x31, 0x20, 0x33, 0x46, 0x34, + 0x59, 0x35, 0x7a, 0x36, 0xa1, 0x37, 0xc2, 0x38, 0xdf, 0x39, 0x01, 0x3b, + 0x0f, 0x3c, 0x27, 0x3d, 0x1f, 0x3e, 0x2e, 0x3f, 0x43, 0x40, 0x5b, 0x41, + 0x73, 0x42, 0x8e, 0x43, 0xaf, 0x44, 0xbc, 0x45, 0xcc, 0x46, 0xd8, 0x47, + 0xec, 0x48, 0xe1, 0x49, 0xd1, 0x4a, 0xc4, 0x4b, 0xb6, 0x4c, 0xa9, 0x4d, + 0x9d, 0x4e, 0x88, 0x4f, 0x75, 0x50, 0x4c, 0x51, 0x3b, 0x52, 0x05, 0x53, + 0xd9, 0x53, 0xa1, 0x54, 0x6f, 0x55, 0x33, 0x56, 0xe5, 0x56, 0x7d, 0x57, + 0x15, 0x58, 0xb3, 0x58, 0x4e, 0x59, 0xdb, 0x59, 0x55, 0x5a, 0xc8, 0x5a, + 0x36, 0x5b, 0xa9, 0x5b, 0x09, 0x5c, 0x5a, 0x5c, 0xab, 0x5c, 0xf1, 0x5c, + 0x34, 0x5d, 0x6a, 0x5d, 0x9e, 0x5d, 0xc1, 0x5d, 0xea, 0x5d, 0x0b, 0x5e, + 0x28, 0x5e, 0x3d, 0x5e, 0x41, 0x5e, 0x51, 0x5e, 0x5f, 0x5e, 0x69, 0x5e, + 0x79, 0x5e, 0x6a, 0x5e, 0x78, 0x5e, 0x76, 0x5e, 0x7f, 0x5e, 0x72, 0x5e, + 0x70, 0x5e, 0x61, 0x5e, 0x61, 0x5e, 0x42, 0x5e, 0x36, 0x5e, 0x2f, 0x5e, + 0x2c, 0x5e, 0x1a, 0x5e, 0xec, 0x5d, 0xbf, 0x5d, 0x94, 0x5d, 0x71, 0x5d, + 0x4c, 0x5d, 0x24, 0x5d, 0xfa, 0x5c, 0xc3, 0x5c, 0x8c, 0x5c, 0x59, 0x5c, + 0x3e, 0x5c, 0x0c, 0x5c, 0xd3, 0x5b, 0xb1, 0x5b, 0x78, 0x5b, 0x45, 0x5b, + 0x14, 0x5b, 0xed, 0x5a, 0xc0, 0x5a, 0x89, 0x5a, 0x4f, 0x5a, 0x16, 0x5a, + 0xe5, 0x59, 0xb5, 0x59, 0x84, 0x59, 0x4e, 0x59, 0x0d, 0x59, 0xcf, 0x58, + 0xa6, 0x58, 0x79, 0x58, 0x3e, 0x58, 0xf8, 0x57, 0xc0, 0x57, 0x83, 0x57, + 0x38, 0x57, 0x03, 0x57, 0xc1, 0x56, 0x65, 0x56, 0xe0, 0x55, 0x52, 0x55, + 0xd0, 0x54, 0x4c, 0x54, 0xbe, 0x53, 0x32, 0x53, 0xa7, 0x52, 0x2a, 0x52, + 0x95, 0x51, 0x09, 0x51, 0x76, 0x50, 0xe9, 0x4f, 0x69, 0x4f, 0xe2, 0x4e, + 0x49, 0x4e, 0xc0, 0x4d, 0x38, 0x4d, 0xbd, 0x4c, 0x2d, 0x4c, 0x98, 0x4b, + 0x07, 0x4b, 0x76, 0x4a, 0xdc, 0x49, 0x4a, 0x49, 0xb9, 0x48, 0x2d, 0x48, + 0x9c, 0x47, 0x19, 0x47, 0x80, 0x46, 0xf9, 0x45, 0x66, 0x45, 0xd6, 0x44, + 0x47, 0x44, 0xb5, 0x43, 0x14, 0x43, 0x74, 0x42, 0xd4, 0x41, 0x42, 0x41, + 0xa4, 0x40, 0x18, 0x40, 0x85, 0x3f, 0xeb, 0x3e, 0x52, 0x3e, 0xb2, 0x3d, + 0x0c, 0x3d, 0x7a, 0x3c, 0xdb, 0x3b, 0x3a, 0x3b, 0x87, 0x3a, 0xe0, 0x39, + 0x29, 0x39, 0x88, 0x38, 0xd1, 0x37, 0x16, 0x37, 0x4d, 0x36, 0x9e, 0x35, + 0xdc, 0x34, 0x19, 0x34, 0x4a, 0x33, 0x83, 0x32, 0xb7, 0x31, 0xec, 0x30, + 0x1c, 0x30, 0x47, 0x2f, 0x71, 0x2e, 0x88, 0x2d, 0xa6, 0x2c, 0xbb, 0x2b, + 0xd0, 0x2a, 0xd8, 0x29, 0xdb, 0x28, 0xe3, 0x27, 0xf5, 0x26, 0xf1, 0x25, + 0xf8, 0x24, 0xdc, 0x23, 0xdb, 0x22, 0xca, 0x21, 0xa7, 0x20, 0x85, 0x1f, + 0x5a, 0x1e, 0x30, 0x1d, 0x0a, 0x1c, 0xd5, 0x1a, 0xa6, 0x19, 0x6d, 0x18, + 0x3d, 0x17, 0xff, 0x15, 0xbf, 0x14, 0x81, 0x13, 0x57, 0x12, 0x15, 0x11, + 0xe0, 0x0f, 0xa2, 0x0e, 0x65, 0x0d, 0x27, 0x0c, 0xf1, 0x0a, 0xb2, 0x09, + 0x77, 0x08, 0x4b, 0x07, 0x0a, 0x06, 0xc9, 0x04, 0x97, 0x03, 0x65, 0x02, + 0x3b, 0x01, 0x03, 0x00, 0xd2, 0xfe, 0x95, 0xfd, 0x6f, 0xfc, 0x50, 0xfb, + 0x19, 0xfa, 0xf0, 0xf8, 0xb8, 0xf7, 0x97, 0xf6, 0x65, 0xf5, 0x48, 0xf4, + 0x24, 0xf3, 0xfe, 0xf1, 0xec, 0xf0, 0xd2, 0xef, 0xa9, 0xee, 0x95, 0xed, + 0x76, 0xec, 0x64, 0xeb, 0x61, 0xea, 0x43, 0xe9, 0x3a, 0xe8, 0x21, 0xe7, + 0x14, 0xe6, 0xff, 0xe4, 0x06, 0xe4, 0x04, 0xe3, 0x04, 0xe2, 0x01, 0xe1, + 0x02, 0xe0, 0x04, 0xdf, 0x16, 0xde, 0x1f, 0xdd, 0x29, 0xdc, 0x2d, 0xdb, + 0x3d, 0xda, 0x45, 0xd9, 0x5a, 0xd8, 0x6f, 0xd7, 0x74, 0xd6, 0x8a, 0xd5, + 0x91, 0xd4, 0xa5, 0xd3, 0xbb, 0xd2, 0xdb, 0xd1, 0x01, 0xd1, 0x17, 0xd0, + 0x42, 0xcf, 0x5e, 0xce, 0x94, 0xcd, 0xb1, 0xcc, 0xe8, 0xcb, 0x04, 0xcb, + 0x29, 0xca, 0x4e, 0xc9, 0x78, 0xc8, 0x99, 0xc7, 0xc4, 0xc6, 0xff, 0xc5, + 0x3d, 0xc5, 0x76, 0xc4, 0xa6, 0xc3, 0xe4, 0xc2, 0x17, 0xc2, 0x4e, 0xc1, + 0x8a, 0xc0, 0xc5, 0xbf, 0x0b, 0xbf, 0x42, 0xbe, 0x8e, 0xbd, 0xd8, 0xbc, + 0x20, 0xbc, 0x60, 0xbb, 0xbb, 0xba, 0x08, 0xba, 0x5a, 0xb9, 0xba, 0xb8, + 0x08, 0xb8, 0x64, 0xb7, 0xb1, 0xb6, 0x0c, 0xb6, 0x5d, 0xb5, 0xbf, 0xb4, + 0x10, 0xb4, 0x7b, 0xb3, 0xd0, 0xb2, 0x3d, 0xb2, 0xa1, 0xb1, 0x0f, 0xb1, + 0x84, 0xb0, 0xf2, 0xaf, 0x63, 0xaf, 0xd3, 0xae, 0x50, 0xae, 0xbd, 0xad, + 0x49, 0xad, 0xc1, 0xac, 0x4d, 0xac, 0xc6, 0xab, 0x56, 0xab, 0xe4, 0xaa, + 0x83, 0xaa, 0x0d, 0xaa, 0xac, 0xa9, 0x49, 0xa9, 0xf3, 0xa8, 0x9e, 0xa8, + 0x4e, 0xa8, 0x07, 0xa8, 0xc5, 0xa7, 0x8d, 0xa7, 0x56, 0xa7, 0x1d, 0xa7, + 0xf6, 0xa6, 0xc7, 0xa6, 0xad, 0xa6, 0x8c, 0xa6, 0x74, 0xa6, 0x58, 0xa6, + 0x47, 0xa6, 0x2d, 0xa6, 0x24, 0xa6, 0x23, 0xa6, 0x21, 0xa6, 0x19, 0xa6, + 0x20, 0xa6, 0x1f, 0xa6, 0x28, 0xa6, 0x3c, 0xa6, 0x4e, 0xa6, 0x59, 0xa6, + 0x6e, 0xa6, 0x84, 0xa6, 0x9a, 0xa6, 0xb7, 0xa6, 0xd4, 0xa6, 0xef, 0xa6, + 0x0a, 0xa7, 0x2f, 0xa7, 0x53, 0xa7, 0x77, 0xa7, 0x9c, 0xa7, 0xbc, 0xa7, + 0xe5, 0xa7, 0x10, 0xa8, 0x35, 0xa8, 0x6d, 0xa8, 0x9b, 0xa8, 0xcb, 0xa8, + 0xf5, 0xa8, 0x23, 0xa9, 0x5a, 0xa9, 0x80, 0xa9, 0xb7, 0xa9, 0xee, 0xa9, + 0x1c, 0xaa, 0x46, 0xaa, 0x78, 0xaa, 0xb2, 0xaa, 0xeb, 0xaa, 0x1a, 0xab, + 0x57, 0xab, 0x84, 0xab, 0xba, 0xab, 0xef, 0xab, 0x22, 0xac, 0x55, 0xac, + 0x88, 0xac, 0xc1, 0xac, 0xf5, 0xac, 0x2a, 0xad, 0x67, 0xad, 0x9f, 0xad, + 0xe0, 0xad, 0x14, 0xae, 0x4c, 0xae, 0x82, 0xae, 0xb8, 0xae, 0xf8, 0xae, + 0x2c, 0xaf, 0x6a, 0xaf, 0x9d, 0xaf, 0xd4, 0xaf, 0x05, 0xb0, 0x38, 0xb0, + 0x77, 0xb0, 0xb2, 0xb0, 0xf8, 0xb0, 0x3c, 0xb1, 0x97, 0xb1, 0x05, 0xb2, + 0x6f, 0xb2, 0xdf, 0xb2, 0x48, 0xb3, 0xb2, 0xb3, 0x16, 0xb4, 0x7b, 0xb4, + 0xe5, 0xb4, 0x54, 0xb5, 0xc3, 0xb5, 0x26, 0xb6, 0x97, 0xb6, 0x03, 0xb7, + 0x68, 0xb7, 0xce, 0xb7, 0x44, 0xb8, 0xae, 0xb8, 0x20, 0xb9, 0x87, 0xb9, + 0xf1, 0xb9, 0x5d, 0xba, 0xc6, 0xba, 0x24, 0xbb, 0xa1, 0xbb, 0x05, 0xbc, + 0x79, 0xbc, 0xdc, 0xbc, 0x4b, 0xbd, 0xba, 0xbd, 0x24, 0xbe, 0x9b, 0xbe, + 0x07, 0xbf, 0x72, 0xbf, 0xe5, 0xbf, 0x46, 0xc0, 0xc3, 0xc0, 0x1f, 0xc1, + 0x91, 0xc1, 0x01, 0xc2, 0x79, 0xc2, 0xf1, 0xc2, 0x66, 0xc3, 0xe5, 0xc3, + 0x55, 0xc4, 0xc8, 0xc4, 0x3e, 0xc5, 0xb3, 0xc5, 0x2d, 0xc6, 0xa7, 0xc6, + 0x27, 0xc7, 0x97, 0xc7, 0x1f, 0xc8, 0xa0, 0xc8, 0x29, 0xc9, 0xad, 0xc9, + 0x36, 0xca, 0xad, 0xca, 0x3d, 0xcb, 0xc0, 0xcb, 0x47, 0xcc, 0xe9, 0xcc, + 0x6f, 0xcd, 0x06, 0xce, 0x84, 0xce, 0x1a, 0xcf, 0xbb, 0xcf, 0x55, 0xd0, + 0xf6, 0xd0, 0x8b, 0xd1, 0x30, 0xd2, 0xd2, 0xd2, 0x79, 0xd3, 0x1c, 0xd4, + 0xcf, 0xd4, 0x83, 0xd5, 0x36, 0xd6, 0xe1, 0xd6, 0x96, 0xd7, 0x5f, 0xd8, + 0x1c, 0xd9, 0xe2, 0xd9, 0xa8, 0xda, 0x6c, 0xdb, 0x43, 0xdc, 0x04, 0xdd, + 0xd8, 0xdd, 0xac, 0xde, 0x8a, 0xdf, 0x5b, 0xe0, 0x39, 0xe1, 0x0b, 0xe2, + 0xf5, 0xe2, 0xde, 0xe3, 0xbc, 0xe4, 0x9e, 0xe5, 0x83, 0xe6, 0x62, 0xe7, + 0x51, 0xe8, 0x34, 0xe9, 0x1e, 0xea, 0x12, 0xeb, 0xf7, 0xeb, 0xe5, 0xec, + 0xc5, 0xed, 0xc2, 0xee, 0xb1, 0xef, 0xa6, 0xf0, 0x90, 0xf1, 0x7e, 0xf2, + 0x6f, 0xf3, 0x56, 0xf4, 0x48, 0xf5, 0x35, 0xf6, 0x29, 0xf7, 0x17, 0xf8, + 0x0a, 0xf9, 0x00, 0xfa, 0xe7, 0xfa, 0xde, 0xfb, 0xc9, 0xfc, 0xc1, 0xfd, + 0xac, 0xfe, 0xae, 0xff, 0xa2, 0x00, 0x8d, 0x01, 0x70, 0x02, 0x62, 0x03, + 0x4e, 0x04, 0x3a, 0x05, 0x26, 0x06, 0x16, 0x07, 0xff, 0x07, 0xf3, 0x08, + 0xda, 0x09, 0xbe, 0x0a, 0xb9, 0x0b, 0xa1, 0x0c, 0x9b, 0x0d, 0x7d, 0x0e, + 0x66, 0x0f, 0x54, 0x10, 0x36, 0x11, 0x20, 0x12, 0x11, 0x13, 0xf3, 0x13, + 0xea, 0x14, 0xd1, 0x15, 0xb6, 0x16, 0x9b, 0x17, 0x83, 0x18, 0x7f, 0x19, + 0x58, 0x1a, 0x53, 0x1b, 0x37, 0x1c, 0x22, 0x1d, 0x0a, 0x1e, 0xf3, 0x1e, + 0xda, 0x1f, 0xca, 0x20, 0xb1, 0x21, 0x96, 0x22, 0x70, 0x23, 0x55, 0x24, + 0x39, 0x25, 0x39, 0x26, 0x1a, 0x27, 0x07, 0x28, 0xe1, 0x28, 0xc5, 0x29, + 0xa7, 0x2a, 0x85, 0x2b, 0x70, 0x2c, 0x4e, 0x2d, 0x3e, 0x2e, 0x19, 0x2f, + 0xf3, 0x2f, 0xdf, 0x30, 0xc0, 0x31, 0xaf, 0x32, 0x93, 0x33, 0x77, 0x34, + 0x48, 0x35, 0x2a, 0x36, 0x0f, 0x37, 0xf8, 0x37, 0xd9, 0x38, 0xbe, 0x39, + 0x8b, 0x3a, 0x74, 0x3b, 0x48, 0x3c, 0x2d, 0x3d, 0xfa, 0x3d, 0xe7, 0x3e, + 0xb0, 0x3f, 0x98, 0x40, 0x67, 0x41, 0x3a, 0x42, 0x16, 0x43, 0xf4, 0x43, + 0xd8, 0x44, 0xa4, 0x45, 0x7c, 0x46, 0x4c, 0x47, 0x2a, 0x48, 0x06, 0x49, + 0xce, 0x49, 0xa5, 0x4a, 0x77, 0x4b, 0x4e, 0x4c, 0x13, 0x4d, 0xdf, 0x4d, + 0xaa, 0x4e, 0x74, 0x4f, 0x3d, 0x50, 0xfc, 0x50, 0xbd, 0x51, 0x8c, 0x52, + 0x3e, 0x53, 0xfe, 0x53, 0x99, 0x54, 0x57, 0x55, 0xfc, 0x55, 0xab, 0x56, + 0x45, 0x57, 0xd6, 0x57, 0x87, 0x58, 0x2f, 0x59, 0xbf, 0x59, 0x48, 0x5a, + 0xc7, 0x5a, 0x54, 0x5b, 0xc8, 0x5b, 0x45, 0x5c, 0xb4, 0x5c, 0x25, 0x5d, + 0x7e, 0x5d, 0xda, 0x5d, 0x36, 0x5e, 0xa5, 0x5e, 0xe9, 0x5e, 0x37, 0x5f, + 0x72, 0x5f, 0xab, 0x5f, 0xe5, 0x5f, 0x1d, 0x60, 0x4f, 0x60, 0x81, 0x60, + 0x9c, 0x60, 0xc3, 0x60, 0xdc, 0x60, 0xf7, 0x60, 0x04, 0x61, 0x16, 0x61, + 0x1b, 0x61, 0x21, 0x61, 0x20, 0x61, 0x0d, 0x61, 0x0b, 0x61, 0xf0, 0x60, + 0xe5, 0x60, 0xc7, 0x60, 0xb3, 0x60, 0x98, 0x60, 0x7c, 0x60, 0x59, 0x60, + 0x4c, 0x60, 0x24, 0x60, 0x0d, 0x60, 0xdf, 0x5f, 0xb7, 0x5f, 0x87, 0x5f, + 0x6b, 0x5f, 0x44, 0x5f, 0x28, 0x5f, 0xf5, 0x5e, 0xbd, 0x5e, 0x8f, 0x5e, + 0x5c, 0x5e, 0x2a, 0x5e, 0xfe, 0x5d, 0xcd, 0x5d, 0xa4, 0x5d, 0x75, 0x5d, + 0x4d, 0x5d, 0x11, 0x5d, 0xdf, 0x5c, 0xa9, 0x5c, 0x78, 0x5c, 0x42, 0x5c, + 0x13, 0x5c, 0xde, 0x5b, 0xaf, 0x5b, 0x75, 0x5b, 0x3e, 0x5b, 0xfd, 0x5a, + 0xbc, 0x5a, 0x90, 0x5a, 0x54, 0x5a, 0x1f, 0x5a, 0xe5, 0x59, 0xc2, 0x59, + 0x80, 0x59, 0x39, 0x59, 0x0a, 0x59, 0xd6, 0x58, 0x96, 0x58, 0x55, 0x58, + 0x1e, 0x58, 0xf1, 0x57, 0xc8, 0x57, 0x7e, 0x57, 0x44, 0x57, 0x11, 0x57, + 0xd4, 0x56, 0x93, 0x56, 0x4c, 0x56, 0x11, 0x56, 0xd7, 0x55, 0xae, 0x55, + 0x72, 0x55, 0x3c, 0x55, 0x0c, 0x55, 0xd1, 0x54, 0x98, 0x54, 0x63, 0x54, + 0x2b, 0x54, 0xf8, 0x53, 0xc6, 0x53, 0x81, 0x53, 0x4b, 0x53, 0x19, 0x53, + 0xea, 0x52, 0xb2, 0x52, 0x7e, 0x52, 0x30, 0x52, 0xc5, 0x51, 0x46, 0x51, + 0xca, 0x50, 0x55, 0x50, 0xd7, 0x4f, 0x5d, 0x4f, 0xe4, 0x4e, 0x79, 0x4e, + 0xfb, 0x4d, 0x83, 0x4d, 0x02, 0x4d, 0x8a, 0x4c, 0x1f, 0x4c, 0x98, 0x4b, + 0x20, 0x4b, 0xa7, 0x4a, 0x36, 0x4a, 0xc0, 0x49, 0x44, 0x49, 0xc3, 0x48, + 0x44, 0x48, 0xd5, 0x47, 0x59, 0x47, 0xe6, 0x46, 0x63, 0x46, 0xf8, 0x45, + 0x79, 0x45, 0xfa, 0x44, 0x80, 0x44, 0x01, 0x44, 0x7a, 0x43, 0x04, 0x43, + 0x85, 0x42, 0x07, 0x42, 0x92, 0x41, 0x17, 0x41, 0x94, 0x40, 0x16, 0x40, + 0x9f, 0x3f, 0x20, 0x3f, 0x9c, 0x3e, 0x29, 0x3e, 0x9c, 0x3d, 0x20, 0x3d, + 0x88, 0x3c, 0x0c, 0x3c, 0x87, 0x3b, 0x07, 0x3b, 0x89, 0x3a, 0xfb, 0x39, + 0x6f, 0x39, 0xe7, 0x38, 0x55, 0x38, 0xcf, 0x37, 0x43, 0x37, 0xb5, 0x36, + 0x2a, 0x36, 0x9c, 0x35, 0x0a, 0x35, 0x83, 0x34, 0xe6, 0x33, 0x53, 0x33, + 0xba, 0x32, 0x1d, 0x32, 0x78, 0x31, 0xcb, 0x30, 0x34, 0x30, 0x8e, 0x2f, + 0xf6, 0x2e, 0x56, 0x2e, 0xab, 0x2d, 0xfe, 0x2c, 0x4c, 0x2c, 0x9f, 0x2b, + 0xed, 0x2a, 0x36, 0x2a, 0x7b, 0x29, 0xb9, 0x28, 0x02, 0x28, 0x41, 0x27, + 0x81, 0x26, 0xb9, 0x25, 0xfb, 0x24, 0x2d, 0x24, 0x66, 0x23, 0x98, 0x22, + 0xc6, 0x21, 0xe9, 0x20, 0x0d, 0x20, 0x28, 0x1f, 0x4c, 0x1e, 0x64, 0x1d, + 0x66, 0x1c, 0x8c, 0x1b, 0x96, 0x1a, 0xac, 0x19, 0xb2, 0x18, 0xbb, 0x17, + 0xc2, 0x16, 0xc7, 0x15, 0xcb, 0x14, 0xcd, 0x13, 0xc4, 0x12, 0xca, 0x11, + 0xb6, 0x10, 0xb8, 0x0f, 0xa3, 0x0e, 0x9e, 0x0d, 0x88, 0x0c, 0x86, 0x0b, + 0x7b, 0x0a, 0x7c, 0x09, 0x6d, 0x08, 0x5b, 0x07, 0x4a, 0x06, 0x38, 0x05, + 0x2f, 0x04, 0x1c, 0x03, 0x10, 0x02, 0xf6, 0x00, 0xe9, 0xff, 0xe5, 0xfe, + 0xcf, 0xfd, 0xc8, 0xfc, 0xb1, 0xfb, 0xa7, 0xfa, 0x8d, 0xf9, 0x7b, 0xf8, + 0x7e, 0xf7, 0x77, 0xf6, 0x68, 0xf5, 0x62, 0xf4, 0x49, 0xf3, 0x42, 0xf2, + 0x41, 0xf1, 0x3e, 0xf0, 0x49, 0xef, 0x47, 0xee, 0x56, 0xed, 0x46, 0xec, + 0x56, 0xeb, 0x5c, 0xea, 0x6c, 0xe9, 0x7d, 0xe8, 0x9c, 0xe7, 0x99, 0xe6, + 0xbf, 0xe5, 0xc9, 0xe4, 0xe5, 0xe3, 0xfd, 0xe2, 0x17, 0xe2, 0x26, 0xe1, + 0x44, 0xe0, 0x6d, 0xdf, 0x9f, 0xde, 0xc5, 0xdd, 0xec, 0xdc, 0x26, 0xdc, + 0x58, 0xdb, 0x91, 0xda, 0xb7, 0xd9, 0xf5, 0xd8, 0x27, 0xd8, 0x63, 0xd7, + 0x96, 0xd6, 0xd5, 0xd5, 0x1a, 0xd5, 0x52, 0xd4, 0x9d, 0xd3, 0xde, 0xd2, + 0x27, 0xd2, 0x6c, 0xd1, 0xb3, 0xd0, 0xf6, 0xcf, 0x51, 0xcf, 0x98, 0xce, + 0xe9, 0xcd, 0x2f, 0xcd, 0x88, 0xcc, 0xdc, 0xcb, 0x41, 0xcb, 0x9f, 0xca, + 0x01, 0xca, 0x60, 0xc9, 0xc4, 0xc8, 0x13, 0xc8, 0x7e, 0xc7, 0xe2, 0xc6, + 0x51, 0xc6, 0xb6, 0xc5, 0x1a, 0xc5, 0x8e, 0xc4, 0xf6, 0xc3, 0x74, 0xc3, + 0xdf, 0xc2, 0x59, 0xc2, 0xd2, 0xc1, 0x47, 0xc1, 0xbe, 0xc0, 0x3b, 0xc0, + 0xbe, 0xbf, 0x3e, 0xbf, 0xc4, 0xbe, 0x39, 0xbe, 0xbf, 0xbd, 0x3e, 0xbd, + 0xd7, 0xbc, 0x5d, 0xbc, 0xec, 0xbb, 0x73, 0xbb, 0x07, 0xbb, 0x96, 0xba, + 0x24, 0xba, 0xb5, 0xb9, 0x49, 0xb9, 0xdd, 0xb8, 0x76, 0xb8, 0x02, 0xb8, + 0xa8, 0xb7, 0x3c, 0xb7, 0xee, 0xb6, 0x82, 0xb6, 0x2b, 0xb6, 0xc3, 0xb5, + 0x6e, 0xb5, 0x14, 0xb5, 0xc4, 0xb4, 0x6b, 0xb4, 0x20, 0xb4, 0xd2, 0xb3, + 0x78, 0xb3, 0x2c, 0xb3, 0xe6, 0xb2, 0x9e, 0xb2, 0x58, 0xb2, 0x1a, 0xb2, + 0xea, 0xb1, 0xa6, 0xb1, 0x63, 0xb1, 0x2b, 0xb1, 0xf3, 0xb0, 0xb8, 0xb0, + 0x7b, 0xb0, 0x4e, 0xb0, 0x20, 0xb0, 0xf9, 0xaf, 0xc6, 0xaf, 0xa2, 0xaf, + 0x84, 0xaf, 0x5e, 0xaf, 0x44, 0xaf, 0x21, 0xaf, 0x06, 0xaf, 0xe9, 0xae, + 0xe2, 0xae, 0xd0, 0xae, 0xc3, 0xae, 0xba, 0xae, 0xc1, 0xae, 0xaf, 0xae, + 0xbc, 0xae, 0xb5, 0xae, 0xc0, 0xae, 0xc3, 0xae, 0xd7, 0xae, 0xdd, 0xae, + 0xfb, 0xae, 0x0a, 0xaf, 0x16, 0xaf, 0x37, 0xaf, 0x4a, 0xaf, 0x70, 0xaf, + 0x86, 0xaf, 0xa9, 0xaf, 0xc7, 0xaf, 0xec, 0xaf, 0x12, 0xb0, 0x42, 0xb0, + 0x66, 0xb0, 0x91, 0xb0, 0xc0, 0xb0, 0xee, 0xb0, 0x1a, 0xb1, 0x4c, 0xb1, + 0x77, 0xb1, 0xb3, 0xb1, 0xdd, 0xb1, 0x10, 0xb2, 0x47, 0xb2, 0x70, 0xb2, + 0xb8, 0xb2, 0xef, 0xb2, 0x26, 0xb3, 0x64, 0xb3, 0x90, 0xb3, 0xd8, 0xb3, + 0x07, 0xb4, 0x4b, 0xb4, 0x83, 0xb4, 0xc7, 0xb4, 0xf4, 0xb4, 0x35, 0xb5, + 0x70, 0xb5, 0xbc, 0xb5, 0xf0, 0xb5, 0x39, 0xb6, 0x7d, 0xb6, 0xb7, 0xb6, + 0xfa, 0xb6, 0x2e, 0xb7, 0x7d, 0xb7, 0xbb, 0xb7, 0x01, 0xb8, 0x39, 0xb8, + 0x80, 0xb8, 0xbd, 0xb8, 0x05, 0xb9, 0x46, 0xb9, 0x94, 0xb9, 0xcd, 0xb9, + 0x17, 0xba, 0x5b, 0xba, 0x9e, 0xba, 0xdf, 0xba, 0x27, 0xbb, 0x6a, 0xbb, + 0xbc, 0xbb, 0xf6, 0xbb, 0x3a, 0xbc, 0x83, 0xbc, 0xc3, 0xbc, 0x16, 0xbd, + 0x58, 0xbd, 0xa2, 0xbd, 0xe0, 0xbd, 0x24, 0xbe, 0x70, 0xbe, 0xa1, 0xbe, + 0xfa, 0xbe, 0x37, 0xbf, 0x8d, 0xbf, 0xc9, 0xbf, 0x1d, 0xc0, 0x5d, 0xc0, + 0xa6, 0xc0, 0xe6, 0xc0, 0x2f, 0xc1, 0x7a, 0xc1, 0xcb, 0xc1, 0x2f, 0xc2, + 0x95, 0xc2, 0xfa, 0xc2, 0x55, 0xc3, 0xbb, 0xc3, 0x1e, 0xc4, 0x86, 0xc4, + 0xec, 0xc4, 0x4b, 0xc5, 0xab, 0xc5, 0x04, 0xc6, 0x72, 0xc6, 0xc6, 0xc6, + 0x3a, 0xc7, 0x8e, 0xc7, 0xfd, 0xc7, 0x5a, 0xc8, 0xc0, 0xc8, 0x17, 0xc9, + 0x79, 0xc9, 0xd5, 0xc9, 0x43, 0xca, 0x98, 0xca, 0x05, 0xcb, 0x64, 0xcb, + 0xc3, 0xcb, 0x1e, 0xcc, 0x81, 0xcc, 0xe3, 0xcc, 0x40, 0xcd, 0xa6, 0xcd, + 0x0a, 0xce, 0x6a, 0xce, 0xc0, 0xce, 0x26, 0xcf, 0x81, 0xcf, 0xf0, 0xcf, + 0x48, 0xd0, 0xad, 0xd0, 0x07, 0xd1, 0x71, 0xd1, 0xca, 0xd1, 0x2b, 0xd2, + 0x8a, 0xd2, 0xed, 0xd2, 0x50, 0xd3, 0xa1, 0xd3, 0x0f, 0xd4, 0x6f, 0xd4, + 0xd6, 0xd4, 0x30, 0xd5, 0x93, 0xd5, 0xf6, 0xd5, 0x55, 0xd6, 0xb5, 0xd6, + 0x12, 0xd7, 0x7b, 0xd7, 0xde, 0xd7, 0x34, 0xd8, 0x93, 0xd8, 0xe9, 0xd8, + 0x61, 0xd9, 0xbb, 0xd9, 0x2b, 0xda, 0x88, 0xda, 0xeb, 0xda, 0x4f, 0xdb, + 0xb9, 0xdb, 0x21, 0xdc, 0x80, 0xdc, 0xf7, 0xdc, 0x53, 0xdd, 0xbb, 0xdd, + 0x2b, 0xde, 0xa4, 0xde, 0x05, 0xdf, 0x74, 0xdf, 0xd8, 0xdf, 0x44, 0xe0, + 0xb4, 0xe0, 0x26, 0xe1, 0x91, 0xe1, 0x01, 0xe2, 0x77, 0xe2, 0xeb, 0xe2, + 0x5e, 0xe3, 0xc7, 0xe3, 0x44, 0xe4, 0xb2, 0xe4, 0x25, 0xe5, 0xa3, 0xe5, + 0x15, 0xe6, 0x97, 0xe6, 0x0b, 0xe7, 0x8b, 0xe7, 0x10, 0xe8, 0x7d, 0xe8, + 0x06, 0xe9, 0x74, 0xe9, 0xff, 0xe9, 0x82, 0xea, 0x01, 0xeb, 0x85, 0xeb, + 0xfa, 0xeb, 0x91, 0xec, 0x07, 0xed, 0x8f, 0xed, 0x15, 0xee, 0x9a, 0xee, + 0x26, 0xef, 0xa5, 0xef, 0x26, 0xf0, 0xb2, 0xf0, 0x3e, 0xf1, 0xca, 0xf1, + 0x45, 0xf2, 0xcc, 0xf2, 0x51, 0xf3, 0xdc, 0xf3, 0x5c, 0xf4, 0xe8, 0xf4, + 0x6e, 0xf5, 0xf9, 0xf5, 0x79, 0xf6, 0xf9, 0xf6, 0x7d, 0xf7, 0x08, 0xf8, + 0x91, 0xf8, 0x18, 0xf9, 0x95, 0xf9, 0x18, 0xfa, 0xa5, 0xfa, 0x21, 0xfb, + 0xa9, 0xfb, 0x2a, 0xfc, 0xa7, 0xfc, 0x23, 0xfd, 0xa3, 0xfd, 0x2b, 0xfe, + 0x9c, 0xfe, 0x2b, 0xff, 0xa0, 0xff, 0x1c, 0x00, 0x9a, 0x00, 0x11, 0x01, + 0x9a, 0x01, 0x14, 0x02, 0x8c, 0x02, 0x07, 0x03, 0x84, 0x03, 0xf7, 0x03, + 0x75, 0x04, 0xf3, 0x04, 0x65, 0x05, 0xe8, 0x05, 0x54, 0x06, 0xd3, 0x06, + 0x48, 0x07, 0xc2, 0x07, 0x38, 0x08, 0xad, 0x08, 0x28, 0x09, 0x99, 0x09, + 0x11, 0x0a, 0x79, 0x0a, 0xf5, 0x0a, 0x5c, 0x0b, 0xd1, 0x0b, 0x3f, 0x0c, + 0xb5, 0x0c, 0x2c, 0x0d, 0x9a, 0x0d, 0x0b, 0x0e, 0x74, 0x0e, 0xe6, 0x0e, + 0x45, 0x0f, 0xbd, 0x0f, 0x2f, 0x10, 0x9a, 0x10, 0x05, 0x11, 0x6c, 0x11, + 0xdb, 0x11, 0x40, 0x12, 0xaa, 0x12, 0x14, 0x13, 0x81, 0x13, 0xe9, 0x13, + 0x4d, 0x14, 0xb9, 0x14, 0x18, 0x15, 0x88, 0x15, 0xe6, 0x15, 0x58, 0x16, + 0xb9, 0x16, 0x1c, 0x17, 0x7e, 0x17, 0xe3, 0x17, 0x43, 0x18, 0xac, 0x18, + 0x08, 0x19, 0x6d, 0x19, 0xce, 0x19, 0x34, 0x1a, 0x90, 0x1a, 0xf5, 0x1a, + 0x53, 0x1b, 0xbb, 0x1b, 0x07, 0x1c, 0x6f, 0x1c, 0xc2, 0x1c, 0x28, 0x1d, + 0x84, 0x1d, 0xe8, 0x1d, 0x35, 0x1e, 0xa2, 0x1e, 0xf8, 0x1e, 0x59, 0x1f, + 0xb8, 0x1f, 0x0c, 0x20, 0x69, 0x20, 0xbe, 0x20, 0x19, 0x21, 0x66, 0x21, + 0xc6, 0x21, 0x1f, 0x22, 0x70, 0x22, 0xbe, 0x22, 0x18, 0x23, 0x72, 0x23, + 0xbf, 0x23, 0x0f, 0x24, 0x67, 0x24, 0xc0, 0x24, 0x08, 0x25, 0x51, 0x25, + 0xa6, 0x25, 0xf4, 0x25, 0x42, 0x26, 0x93, 0x26, 0xd6, 0x26, 0x25, 0x27, + 0x6c, 0x27, 0xb7, 0x27, 0x07, 0x28, 0x49, 0x28, 0x96, 0x28, 0xda, 0x28, + 0x22, 0x29, 0x66, 0x29, 0xa4, 0x29, 0xe8, 0x29, 0x20, 0x2a, 0x62, 0x2a, + 0xa9, 0x2a, 0xe5, 0x2a, 0x21, 0x2b, 0x5a, 0x2b, 0x97, 0x2b, 0xc1, 0x2b, + 0xfe, 0x2b, 0x28, 0x2c, 0x57, 0x2c, 0x88, 0x2c, 0xae, 0x2c, 0xd3, 0x2c, + 0xfa, 0x2c, 0x17, 0x2d, 0x33, 0x2d, 0x4b, 0x2d, 0x5d, 0x2d, 0x68, 0x2d, + 0x81, 0x2d, 0x92, 0x2d, 0x9e, 0x2d, 0xa9, 0x2d, 0xbb, 0x2d, 0xc3, 0x2d, + 0xcd, 0x2d, 0xd5, 0x2d, 0xcd, 0x2d, 0xdc, 0x2d, 0xe3, 0x2d, 0xe1, 0x2d, + 0xdd, 0x2d, 0xd9, 0x2d, 0xd7, 0x2d, 0xcf, 0x2d, 0xe0, 0x2d, 0xd2, 0x2d, + 0xd2, 0x2d, 0xcb, 0x2d, 0xb7, 0x2d, 0xb6, 0x2d, 0xa1, 0x2d, 0x9e, 0x2d, + 0x8b, 0x2d, 0x84, 0x2d, 0x68, 0x2d, 0x6a, 0x2d, 0x4e, 0x2d, 0x45, 0x2d, + 0x2f, 0x2d, 0x18, 0x2d, 0x15, 0x2d, 0xef, 0x2c, 0xe8, 0x2c, 0xc9, 0x2c, + 0xc7, 0x2c, 0xaa, 0x2c, 0x9b, 0x2c, 0x7c, 0x2c, 0x64, 0x2c, 0x3c, 0x2c, + 0x2e, 0x2c, 0x16, 0x2c, 0x05, 0x2c, 0xe1, 0x2b, 0xc8, 0x2b, 0xb5, 0x2b, + 0x9a, 0x2b, 0x7c, 0x2b, 0x61, 0x2b, 0x3f, 0x2b, 0x21, 0x2b, 0x01, 0x2b, + 0xee, 0x2a, 0xd0, 0x2a, 0xb3, 0x2a, 0x95, 0x2a, 0x6d, 0x2a, 0x50, 0x2a, + 0x2b, 0x2a, 0x0b, 0x2a, 0xe9, 0x29, 0xd1, 0x29, 0xa8, 0x29, 0x97, 0x29, + 0x6c, 0x29, 0x51, 0x29, 0x24, 0x29, 0x03, 0x29, 0xe6, 0x28, 0xbe, 0x28, + 0xa1, 0x28, 0x80, 0x28, 0x64, 0x28, 0x38, 0x28, 0x12, 0x28, 0xf0, 0x27, + 0xd3, 0x27, 0xac, 0x27, 0x94, 0x27, 0x67, 0x27, 0x4a, 0x27, 0x1c, 0x27, + 0xf7, 0x26, 0xd1, 0x26, 0xb6, 0x26, 0x8d, 0x26, 0x6e, 0x26, 0x4b, 0x26, + 0x25, 0x26, 0x02, 0x26, 0xd8, 0x25, 0xbe, 0x25, 0x93, 0x25, 0x7c, 0x25, + 0x4a, 0x25, 0x27, 0x25, 0x07, 0x25, 0xdc, 0x24, 0xbb, 0x24, 0x9a, 0x24, + 0x78, 0x24, 0x4c, 0x24, 0x26, 0x24, 0x00, 0x24, 0xd7, 0x23, 0xc0, 0x23, + 0x94, 0x23, 0x71, 0x23, 0x45, 0x23, 0x1c, 0x23, 0x00, 0x23, 0xd4, 0x22, + 0xb5, 0x22, 0x8e, 0x22, 0x67, 0x22, 0x39, 0x22, 0x00, 0x22, 0xbd, 0x21, + 0x87, 0x21, 0x46, 0x21, 0x01, 0x21, 0xca, 0x20, 0x89, 0x20, 0x4a, 0x20, + 0x17, 0x20, 0xd6, 0x1f, 0x9a, 0x1f, 0x5e, 0x1f, 0x20, 0x1f, 0xe0, 0x1e, + 0xa3, 0x1e, 0x5f, 0x1e, 0x29, 0x1e, 0xf0, 0x1d, 0xb8, 0x1d, 0x78, 0x1d, + 0x36, 0x1d, 0x04, 0x1d, 0xc6, 0x1c, 0x8b, 0x1c, 0x4d, 0x1c, 0x18, 0x1c, + 0xd9, 0x1b, 0x97, 0x1b, 0x5c, 0x1b, 0x2b, 0x1b, 0xf4, 0x1a, 0xb1, 0x1a, + 0x7c, 0x1a, 0x32, 0x1a, 0x02, 0x1a, 0xc6, 0x19, 0x8b, 0x19, 0x59, 0x19, + 0x10, 0x19, 0xd7, 0x18, 0x9c, 0x18, 0x62, 0x18, 0x22, 0x18, 0xe8, 0x17, + 0xb1, 0x17, 0x7c, 0x17, 0x34, 0x17, 0xf9, 0x16, 0xc0, 0x16, 0x8b, 0x16, + 0x55, 0x16, 0x14, 0x16, 0xdd, 0x15, 0x9f, 0x15, 0x65, 0x15, 0x2b, 0x15, + 0xea, 0x14, 0xb9, 0x14, 0x70, 0x14, 0x3d, 0x14, 0x05, 0x14, 0xc1, 0x13, + 0x86, 0x13, 0x45, 0x13, 0x09, 0x13, 0xca, 0x12, 0x90, 0x12, 0x57, 0x12, + 0x1a, 0x12, 0xe1, 0x11, 0x9b, 0x11, 0x61, 0x11, 0x1d, 0x11, 0xe1, 0x10, + 0x9d, 0x10, 0x64, 0x10, 0x17, 0x10, 0xde, 0x0f, 0xa1, 0x0f, 0x60, 0x0f, + 0x1b, 0x0f, 0xd8, 0x0e, 0x90, 0x0e, 0x5b, 0x0e, 0x0e, 0x0e, 0xd3, 0x0d, + 0x86, 0x0d, 0x4d, 0x0d, 0xf5, 0x0c, 0xba, 0x0c, 0x68, 0x0c, 0x2a, 0x0c, + 0xde, 0x0b, 0x94, 0x0b, 0x4e, 0x0b, 0x07, 0x0b, 0xbb, 0x0a, 0x6c, 0x0a, + 0x25, 0x0a, 0xd4, 0x09, 0x89, 0x09, 0x39, 0x09, 0xe6, 0x08, 0xa3, 0x08, + 0x4f, 0x08, 0x02, 0x08, 0xa7, 0x07, 0x5f, 0x07, 0x08, 0x07, 0xba, 0x06, + 0x68, 0x06, 0x1f, 0x06, 0xc5, 0x05, 0x7a, 0x05, 0x1f, 0x05, 0xd7, 0x04, + 0x85, 0x04, 0x31, 0x04, 0xde, 0x03, 0x89, 0x03, 0x3a, 0x03, 0xe9, 0x02, + 0x96, 0x02, 0x47, 0x02, 0xf7, 0x01, 0xa4, 0x01, 0x5d, 0x01, 0x06, 0x01, + 0xb9, 0x00 +}; +unsigned int kick_raw_len = 6350; diff --git a/third-party/TeensyVariablePlayback/examples/midilooper/CMakeLists.txt b/third-party/TeensyVariablePlayback/examples/midilooper/CMakeLists.txt new file mode 100644 index 0000000..2e2acbb --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/midilooper/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.10) +project(sampleloader) +set(CMAKE_CXX_STANDARD 14) +teensy_include_directories(../../src) + +import_arduino_library(sampleflashloader ${DEPSPATH}/teensy-sample-flashloader/src) +import_arduino_library(midi ${DEPSPATH}/MIDI/src) + +teensy_add_executable(sampleloader sampleloader.ino) +teensy_target_link_libraries(sampleloader midi sampleflashloader SD SdFat Audio teensy_variable_playback cores arm_math SPI Wire SerialFlash ) diff --git a/third-party/TeensyVariablePlayback/examples/midilooper/midilooper.ino b/third-party/TeensyVariablePlayback/examples/midilooper/midilooper.ino new file mode 100644 index 0000000..dd95858 --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/midilooper/midilooper.ino @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include "flashloader.h" + +// GUItool: begin automatically generated code +AudioPlayArrayResmp rraw_a1; //xy=321,513 +AudioOutputI2S i2s1; //xy=675,518 +AudioConnection patchCord1(rraw_a1, 0, i2s1, 0); +AudioConnection patchCord2(rraw_a1, 0, i2s1, 1); +AudioControlSGTL5000 sgtl5000_1; //xy=521,588 +// GUItool: end automatically generated code +#define A14 10 + +MIDI_CREATE_DEFAULT_INSTANCE(); +const int analogInPin = A14; +newdigate::audiosample *sample; + +double getPlaybackRate(int16_t analog) { //analog: 0..1023 + return (analog - 512.0) / 512.0; +} + +float calcFrequency(uint8_t note) { + float result = 440.0 * powf(2.0, (note-69) / 12.0); + return result; +} + +void handleNoteOn(uint8_t channel, uint8_t pitch, uint8_t velocity) +{ + rraw_a1.setLoopType(loop_type::looptype_repeat); + float freq = calcFrequency(pitch); + uint32_t numSamples = 44100 / freq; + rraw_a1.startLoop(numSamples); +} + +void handleNoteOff(uint8_t channel, uint8_t pitch, uint8_t velocity) +{ + rraw_a1.setLoopType(loop_type::looptype_none); +} + +void setup() { + analogReference(0); + pinMode(analogInPin, INPUT_DISABLE); // i.e. Analog + + Serial.begin(9600); + while (!SD.begin(BUILTIN_SDCARD)) { + Serial.println("initialization failed!"); + delay(1000); + } + + MIDI.setHandleNoteOn(handleNoteOn); + MIDI.setHandleNoteOff(handleNoteOff); + MIDI.begin(MIDI_CHANNEL_OMNI); + + sgtl5000_1.enable(); + sgtl5000_1.volume(0.5f, 0.5f); + + rraw_a1.enableInterpolation(true); + int newsensorValue = analogRead(analogInPin); + rraw_a1.setPlaybackRate(getPlaybackRate(newsensorValue)); + newdigate::flashloader loader; + sample = loader.loadSample("MONKS.RAW"); + + AudioMemory(50); + Serial.println("setup done"); +} + +void loop() { + int newsensorValue = analogRead(analogInPin); + rraw_a1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 500) { + if (!rraw_a1.isPlaying()) { + rraw_a1.play(sample->sampledata, sample->samplesize/2); + lastSamplePlayed = currentMillis; + + Serial.print("Memory: "); + Serial.print(AudioMemoryUsage()); + Serial.print(","); + Serial.print(AudioMemoryUsageMax()); + Serial.println(); + } + } + delay(10); +} diff --git a/third-party/TeensyVariablePlayback/examples/sampleloader/CMakeLists.txt b/third-party/TeensyVariablePlayback/examples/sampleloader/CMakeLists.txt new file mode 100644 index 0000000..916c55c --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/sampleloader/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.10) +project(sampleloader) +set(CMAKE_CXX_STANDARD 14) +teensy_include_directories(../../src) + +import_arduino_library(sampleflashloader ${DEPSPATH}/teensy-sample-flashloader/src) + +teensy_add_executable(sampleloader sampleloader.ino) +teensy_target_link_libraries(sampleloader sampleflashloader SD SdFat Audio teensy_variable_playback cores arm_math SPI Wire SerialFlash ) diff --git a/third-party/TeensyVariablePlayback/examples/sampleloader/README.md b/third-party/TeensyVariablePlayback/examples/sampleloader/README.md new file mode 100644 index 0000000..9280162 --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/sampleloader/README.md @@ -0,0 +1 @@ +this example uses [teensy-sample-flashloader](https://github.com/newdigate/teensy-sample-flashloader) to copy samples from the uSD card to the external flash memory diff --git a/third-party/TeensyVariablePlayback/examples/sampleloader/sampleloader.ino b/third-party/TeensyVariablePlayback/examples/sampleloader/sampleloader.ino new file mode 100644 index 0000000..605621c --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/sampleloader/sampleloader.ino @@ -0,0 +1,66 @@ +// Plays a RAW (16-bit signed) PCM audio file at slower or faster rate +// this example plays a sample stored in an array +#include +#include +#include +#include "flashloader.h" + +// GUItool: begin automatically generated code +AudioPlayArrayResmp rraw_a1; //xy=321,513 +AudioOutputI2S i2s1; //xy=675,518 +AudioConnection patchCord1(rraw_a1, 0, i2s1, 0); +AudioConnection patchCord2(rraw_a1, 0, i2s1, 1); +AudioControlSGTL5000 sgtl5000_1; //xy=521,588 +// GUItool: end automatically generated code +#define A14 10 + +unsigned long lastSamplePlayed = 0; +const int analogInPin = A14; +newdigate::audiosample *sample; + +double getPlaybackRate(int16_t analog) { //analog: 0..1023 + return (analog - 512.0) / 512.0; +} + +void setup() { + analogReference(0); + pinMode(analogInPin, INPUT_DISABLE); // i.e. Analog + + Serial.begin(9600); + while (!SD.begin(BUILTIN_SDCARD)) { + Serial.println("initialization failed!"); + delay(1000); + } + + sgtl5000_1.enable(); + sgtl5000_1.volume(0.5f, 0.5f); + + rraw_a1.enableInterpolation(true); + int newsensorValue = analogRead(analogInPin); + rraw_a1.setPlaybackRate(getPlaybackRate(newsensorValue)); + newdigate::flashloader loader; + sample = loader.loadSample("KICK.RAW"); + + AudioMemory(20); + Serial.println("setup done"); +} + +void loop() { + int newsensorValue = analogRead(analogInPin); + rraw_a1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 500) { + if (!rraw_a1.isPlaying()) { + rraw_a1.playRaw(sample->sampledata, sample->samplesize/2, 1); + lastSamplePlayed = currentMillis; + + Serial.print("Memory: "); + Serial.print(AudioMemoryUsage()); + Serial.print(","); + Serial.print(AudioMemoryUsageMax()); + Serial.println(); + } + } + delay(10); +} diff --git a/third-party/TeensyVariablePlayback/examples/sd_play_all/CMakeLists.txt b/third-party/TeensyVariablePlayback/examples/sd_play_all/CMakeLists.txt new file mode 100644 index 0000000..77da493 --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/sd_play_all/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.10) +project(sd_play_all) +set(CMAKE_CXX_STANDARD 14) +teensy_include_directories(../../src) +teensy_add_executable(sd_play_all sd_play_all.ino) +teensy_target_link_libraries(sd_play_all SD SdFat teensy_variable_playback Audio SPI SerialFlash cores Wire arm_math) diff --git a/third-party/TeensyVariablePlayback/examples/sd_play_all/sd_play_all.ino b/third-party/TeensyVariablePlayback/examples/sd_play_all/sd_play_all.ino new file mode 100644 index 0000000..41d190d --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/sd_play_all/sd_play_all.ino @@ -0,0 +1,147 @@ +// Plays all WAV files from the root directory on the SD card +#include +#include +#include +#include + +// GUItool: begin automatically generated code +AudioPlaySdResmp playSd1; //xy=324,457 +AudioOutputI2S i2s2; //xy=840.8571472167969,445.5714416503906 +AudioConnection patchCord1(playSd1, 0, i2s2, 0); +AudioConnection patchCord2(playSd1, 1, i2s2, 1); +AudioControlSGTL5000 audioShield; +// GUItool: end automatically generated code + +#define A14 10 + +char** _filenames = nullptr; +uint16_t _fileIndex = 0; +uint16_t _numWaveFiles = 0; + +const int analogInPin = A14; +unsigned long lastSamplePlayed = 0; + +double getPlaybackRate(int16_t analog) { //analog: 0..1023 + return (analog - 512.0) / 512.0; +} + +uint16_t getNumWavFilesInDirectory(char *directory); +void populateFilenames(char *directory, char **filenames); + +void setup() { + analogReference(0); + pinMode(analogInPin, INPUT_DISABLE); // i.e. Analog + + Serial.begin(57600); + + if (!(SD.begin(BUILTIN_SDCARD))) { + // stop here if no SD card, but print a message + while (1) { + Serial.println("Unable to access the SD card"); + delay(500); + } + } + audioShield.enable(); + audioShield.volume(0.5); + + playSd1.enableInterpolation(true); + int newsensorValue = analogRead(analogInPin); + playSd1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + _numWaveFiles = getNumWavFilesInDirectory("/"); + Serial.printf("Num wave files: %d\n", _numWaveFiles); + _filenames = new char*[_numWaveFiles]; + populateFilenames("/", _filenames); + + AudioMemory(24); +} + +void loop() { + + int newsensorValue = analogRead(analogInPin); + playSd1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 1000) { + if (!playSd1.isPlaying()) { + + if (playSd1.playWav(_filenames[_fileIndex])) { + lastSamplePlayed = currentMillis; + Serial.printf("playing %s\n", _filenames[_fileIndex]); + } + _fileIndex++; + _fileIndex %= _numWaveFiles; + Serial.print("Memory: "); + Serial.print(AudioMemoryUsage()); + Serial.print(","); + Serial.print(AudioMemoryUsageMax()); + Serial.println(); + } + } + delay(10); +} + +uint16_t getNumWavFilesInDirectory(char *directory) { + File dir = SD.open(directory); + uint16_t numWaveFiles = 0; + + while (true) { + + File files = dir.openNextFile(); + if (!files) { + //If no more files, break out. + break; + } + + String curfile = files.name(); //put file in string + + int m = curfile.lastIndexOf(".WAV"); + int a = curfile.lastIndexOf(".wav"); + int underscore = curfile.indexOf("_"); + + // if returned results is more then 0 add them to the list. + if ((m > 0 || a > 0) && (underscore != 0)) { + numWaveFiles++; + } + + files.close(); + } + // close + dir.close(); + return numWaveFiles; +} + +void populateFilenames(char *directory, char **filenames) { + File dir = SD.open(directory); + uint16_t index = 0; + + while (true) { + + File files = dir.openNextFile(); + if (!files) { + //If no more files, break out. + break; + } + + String curfile = files.name(); //put file in string + + int m = curfile.lastIndexOf(".WAV"); + int a = curfile.lastIndexOf(".wav"); + int underscore = curfile.indexOf("_"); + + // if returned results is more then 0 add them to the list. + if ((m > 0 || a > 0) && (underscore != 0)) { + filenames[index] = new char[curfile.length()+1] {0}; + memcpy(filenames[index], curfile.c_str(), curfile.length()); + index++; + } + files.close(); + } + // close + dir.close(); +} + +namespace std { + void __throw_bad_function_call() {} + void __throw_length_error(char const*) {} +} diff --git a/third-party/TeensyVariablePlayback/examples/sd_raw/CMakeLists.txt b/third-party/TeensyVariablePlayback/examples/sd_raw/CMakeLists.txt new file mode 100644 index 0000000..52de86b --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/sd_raw/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.10) +project(sd_raw) +set(CMAKE_CXX_STANDARD 14) +teensy_include_directories(../../src) +teensy_add_executable(sd_raw sd_raw.ino) +teensy_target_link_libraries(sd_raw SD SdFat teensy_variable_playback Audio SPI SerialFlash cores Wire arm_math) diff --git a/third-party/TeensyVariablePlayback/examples/sd_raw/sd_raw.ino b/third-party/TeensyVariablePlayback/examples/sd_raw/sd_raw.ino new file mode 100644 index 0000000..d651c88 --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/sd_raw/sd_raw.ino @@ -0,0 +1,74 @@ +// Plays a RAW (16-bit signed) PCM audio file at slower or faster rate +// this example requires an uSD-card inserted to teensy 3.6 with a file called DEMO.RAW +#include +#include +#include +#include + +// GUItool: begin automatically generated code +AudioPlaySdResmp playSdRaw1; //xy=324,457 +AudioOutputI2S i2s2; //xy=840.8571472167969,445.5714416503906 +AudioConnection patchCord1(playSdRaw1, 0, i2s2, 0); +AudioConnection patchCord2(playSdRaw1, 0, i2s2, 1); +AudioControlSGTL5000 audioShield; +// GUItool: end automatically generated code + +#define A14 10 + +const char* _filename = "DEMO.RAW"; +const int analogInPin = A14; +unsigned long lastSamplePlayed = 0; + +double getPlaybackRate(int16_t analog) { //analog: 0..1023 + return (analog - 512.0) / 512.0; +} + +void setup() { + analogReference(0); + pinMode(analogInPin, INPUT_DISABLE); // i.e. Analog + + Serial.begin(57600); + + if (!(SD.begin(BUILTIN_SDCARD))) { + // stop here if no SD card, but print a message + while (1) { + Serial.println("Unable to access the SD card"); + delay(500); + } + } + audioShield.enable(); + audioShield.volume(0.5); + + playSdRaw1.enableInterpolation(true); + int newsensorValue = analogRead(analogInPin); + playSdRaw1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + AudioMemory(24); +} + +void loop() { + + int newsensorValue = analogRead(analogInPin); + playSdRaw1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 500) { + if (!playSdRaw1.isPlaying()) { + playSdRaw1.playRaw(_filename, 1); + lastSamplePlayed = currentMillis; + + Serial.print("Memory: "); + Serial.print(AudioMemoryUsage()); + Serial.print(","); + Serial.print(AudioMemoryUsageMax()); + Serial.println(); + } + } + delay(10); +} + + +namespace std { + void __throw_bad_function_call() {} + void __throw_length_error(char const*) {} +} \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/examples/sd_wav/CMakeLists.txt b/third-party/TeensyVariablePlayback/examples/sd_wav/CMakeLists.txt new file mode 100644 index 0000000..018e7a7 --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/sd_wav/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.10) +project(sd_wav) +set(CMAKE_CXX_STANDARD 14) +teensy_include_directories(../../src) +teensy_add_executable(sd_wav sd_wav.ino) +teensy_target_link_libraries(sd_wav SD SdFat teensy_variable_playback Audio SPI SerialFlash cores Wire arm_math) diff --git a/third-party/TeensyVariablePlayback/examples/sd_wav/sd_wav.ino b/third-party/TeensyVariablePlayback/examples/sd_wav/sd_wav.ino new file mode 100644 index 0000000..45bc4cd --- /dev/null +++ b/third-party/TeensyVariablePlayback/examples/sd_wav/sd_wav.ino @@ -0,0 +1,81 @@ +// Plays a Wav (16-bit signed) PCM audio file at slower or faster rate +// this example requires an uSD-card inserted to teensy 3.6 with a file called DEMO.WAV +#include +#include +#include +#include + +// GUItool: begin automatically generated code +AudioPlaySdResmp playSdWav1; //xy=324,457 +AudioOutputI2S i2s2; //xy=840.8571472167969,445.5714416503906 +AudioConnection patchCord1(playSdWav1, 0, i2s2, 0); +AudioConnection patchCord2(playSdWav1, 0, i2s2, 1); +AudioControlSGTL5000 audioShield; +// GUItool: end automatically generated code + +#define A14 10 + +char* _filename = "DEMO.WAV"; +const int analogInPin = A14; +unsigned long lastSamplePlayed = 0; + +double getPlaybackRate(int16_t analog) { //analog: 0..1023 + return (analog - 512.0) / 512.0; +} + +void setup() { + analogReference(0); + pinMode(analogInPin, INPUT_DISABLE); // i.e. Analog + + Serial.begin(57600); + + if (!(SD.begin(BUILTIN_SDCARD))) { + // stop here if no SD card, but print a message + while (1) { + Serial.println("Unable to access the SD card"); + delay(500); + } + } + + AudioMemory(24); + + audioShield.enable(); + audioShield.volume(0.5); + + playSdWav1.enableInterpolation(true); + int newsensorValue = analogRead(analogInPin); + playSdWav1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + Serial.println("playing..."); +} + +void loop() { + int newsensorValue = analogRead(analogInPin); + playSdWav1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 500) { + if (!playSdWav1.isPlaying()) { + playSdWav1.playWav(_filename); + lastSamplePlayed = currentMillis; + + Serial.print("all="); + Serial.print(AudioProcessorUsage()); + Serial.print(","); + Serial.print(AudioProcessorUsageMax()); + Serial.print(" "); + Serial.print("Memory: "); + Serial.print(AudioMemoryUsage()); + Serial.print(","); + Serial.print(AudioMemoryUsageMax()); + Serial.println(); + } + } + delay(10); +} + + +namespace std { + void __throw_bad_function_call() {} + void __throw_length_error(char const*) {} +} \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/extras/linux/array/CMakeLists.txt b/third-party/TeensyVariablePlayback/extras/linux/array/CMakeLists.txt new file mode 100644 index 0000000..aa54190 --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/linux/array/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.10) +project(array) +set(CMAKE_CXX_STANDARD 14) + +find_package(teensy_x86_stubs) +include_directories(${teensy_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs) +include_directories(${teensy_audio_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_x86_sd_stubs) +include_directories(${teensy_x86_sd_stubs_INCLUDE_DIR}) + +include_directories(../../../src) + +add_executable(array array.cpp) + +target_link_libraries(array ${teensy_x86_stubs_LIBS}) +target_link_libraries(array ${teensy_audio_x86_stubs_LIBS}) +target_link_libraries(array ${teensy_x86_sd_stubs_LIBS}) +target_link_libraries(array teensy_variable_playback) diff --git a/third-party/TeensyVariablePlayback/extras/linux/array/array.cpp b/third-party/TeensyVariablePlayback/extras/linux/array/array.cpp new file mode 100644 index 0000000..0a26672 --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/linux/array/array.cpp @@ -0,0 +1,579 @@ +// Plays a RAW (16-bit signed) PCM audio file at slower or faster rate +// this example plays a sample stored in an array +#include +#include +#include "playarrayresmp.h" + +// GUItool: begin automatically generated code +AudioPlayArrayResmp rraw_a1; //xy=321,513 +AudioOutputI2S i2s1; //xy=675,518 +AudioConnection patchCord1(rraw_a1, 0, i2s1, 0); +AudioConnection patchCord2(rraw_a1, 0, i2s1, 1); +AudioControlSGTL5000 sgtl5000_1; //xy=521,588 +// GUItool: end automatically generated code + +extern unsigned int kick_raw_len; +extern unsigned char kick_raw[]; + +void setup() { + Serial.begin(9600); + AudioMemory(20); + sgtl5000_1.enable(); + sgtl5000_1.volume(0.5f, 0.5f); + + rraw_a1.setPlaybackRate(0.5); + rraw_a1.playRaw((int16_t*)kick_raw, kick_raw_len/2, 1); + Serial.println("setup done"); +} + +void loop() { + if (!rraw_a1.isPlaying()) { + delay(1000); + rraw_a1.playRaw((int16_t*)kick_raw, kick_raw_len/2, 1); + } else + delay(100); +} + +#ifdef BUILD_FOR_LINUX +int main() { + initialize_mock_arduino(); + setup(); + while(true){ + loop(); + } +} +#endif + +unsigned char kick_raw[] = { + 0x99, 0x02, 0xd7, 0x02, 0xfa, 0x02, 0x5f, 0x03, 0xc1, 0x03, 0x2a, 0x04, + 0xad, 0x04, 0xa5, 0x05, 0x76, 0x06, 0x2f, 0x07, 0x9e, 0x07, 0xe2, 0x07, + 0x43, 0x08, 0x92, 0x08, 0xb2, 0x08, 0xe8, 0x08, 0x16, 0x09, 0xda, 0x08, + 0x51, 0x08, 0x01, 0x08, 0x25, 0x08, 0x70, 0x08, 0xc3, 0x08, 0x23, 0x09, + 0x95, 0x09, 0x19, 0x0a, 0x83, 0x0a, 0x7e, 0x0a, 0xd0, 0x0a, 0x65, 0x0b, + 0xf6, 0x0b, 0x89, 0x0c, 0xd1, 0x0c, 0xcf, 0x0c, 0x1a, 0x0d, 0xe5, 0x0d, + 0x5e, 0x0e, 0xbb, 0x0e, 0xec, 0x0e, 0xd9, 0x0e, 0x07, 0x0f, 0xc8, 0x0f, + 0x2a, 0x10, 0x04, 0x10, 0x28, 0x10, 0x54, 0x11, 0x8e, 0x13, 0x4b, 0x16, + 0x09, 0x19, 0x91, 0x1b, 0xf7, 0x1d, 0x55, 0x20, 0xd1, 0x22, 0xcb, 0x25, + 0x4d, 0x29, 0xa8, 0x2c, 0x7f, 0x2f, 0xda, 0x31, 0xac, 0x34, 0x0a, 0x3a, + 0x24, 0x47, 0x9d, 0x5b, 0xe9, 0x67, 0x29, 0x67, 0x24, 0x66, 0x26, 0x66, + 0xd2, 0x65, 0x9c, 0x65, 0x38, 0x65, 0x05, 0x65, 0x9f, 0x64, 0x64, 0x64, + 0x12, 0x64, 0xce, 0x63, 0x7c, 0x63, 0x32, 0x63, 0xe6, 0x62, 0x97, 0x62, + 0x49, 0x62, 0x01, 0x62, 0xb3, 0x61, 0x63, 0x61, 0x15, 0x61, 0xc4, 0x60, + 0x75, 0x60, 0x20, 0x60, 0xce, 0x5f, 0x7a, 0x5f, 0x28, 0x5f, 0xd5, 0x5e, + 0x81, 0x5e, 0x2d, 0x5e, 0xd3, 0x5d, 0x80, 0x5d, 0x2e, 0x5d, 0xe6, 0x5c, + 0x1a, 0x5c, 0x16, 0x5a, 0x01, 0x58, 0xb9, 0x56, 0x6d, 0x55, 0xf4, 0x53, + 0x49, 0x52, 0x83, 0x50, 0x87, 0x4e, 0x5f, 0x4c, 0x68, 0x4a, 0x5c, 0x48, + 0x62, 0x46, 0x5a, 0x44, 0xe2, 0x41, 0x08, 0x3f, 0x1c, 0x3c, 0x44, 0x39, + 0x35, 0x36, 0xcb, 0x32, 0xaf, 0x2f, 0xc8, 0x2c, 0xf8, 0x29, 0x55, 0x27, + 0x6a, 0x24, 0x0f, 0x21, 0x5e, 0x1d, 0xc3, 0x19, 0x7b, 0x16, 0x71, 0x13, + 0x6c, 0x10, 0x00, 0x0d, 0xd2, 0x08, 0x7f, 0x04, 0x7a, 0x01, 0x43, 0xff, + 0xb9, 0xfc, 0xfa, 0xf9, 0x3b, 0xf7, 0xcb, 0xf4, 0x2b, 0xf2, 0x02, 0xef, + 0x0c, 0xec, 0x3d, 0xe9, 0x21, 0xe6, 0xa6, 0xe2, 0x8a, 0xdf, 0x00, 0xdd, + 0xbc, 0xda, 0x9e, 0xd8, 0xc1, 0xd6, 0xd6, 0xd4, 0xd6, 0xd2, 0xad, 0xd0, + 0x5f, 0xce, 0xf0, 0xcb, 0xe9, 0xc9, 0x61, 0xc8, 0x75, 0xc7, 0x97, 0xc6, + 0x3e, 0xc5, 0x07, 0xc4, 0x8e, 0xc3, 0x18, 0xc3, 0x3a, 0xc2, 0x15, 0xc1, + 0x0e, 0xc0, 0xb3, 0xbf, 0xcf, 0xbf, 0xf8, 0xbf, 0xcc, 0xbf, 0x72, 0xbf, + 0x41, 0xbf, 0x2b, 0xbf, 0xe2, 0xbe, 0x99, 0xbe, 0x4e, 0xbe, 0x0e, 0xbe, + 0xcd, 0xbd, 0x7c, 0xbd, 0x8a, 0xbd, 0x88, 0xbd, 0x04, 0xbd, 0x0c, 0xbc, + 0xb3, 0xbb, 0xf6, 0xbb, 0xf1, 0xbb, 0x12, 0xbc, 0x6f, 0xbc, 0xcb, 0xbc, + 0xe4, 0xbc, 0x33, 0xbd, 0x1b, 0xbe, 0xac, 0xbe, 0x1e, 0xbf, 0x91, 0xbf, + 0x50, 0xc0, 0x40, 0xc1, 0x3d, 0xc2, 0x32, 0xc3, 0xdf, 0xc3, 0xad, 0xc4, + 0x77, 0xc5, 0xbe, 0xc6, 0xc7, 0xc8, 0x1d, 0xcb, 0x0e, 0xcd, 0x83, 0xce, + 0xf1, 0xcf, 0xb4, 0xd1, 0x7d, 0xd3, 0x86, 0xd5, 0x89, 0xd7, 0xd2, 0xd9, + 0x34, 0xdc, 0x28, 0xde, 0x23, 0xe0, 0x33, 0xe2, 0x0a, 0xe4, 0x59, 0xe5, + 0xfc, 0xe6, 0x98, 0xe9, 0x30, 0xec, 0x91, 0xee, 0xc2, 0xf0, 0x0d, 0xf3, + 0x35, 0xf5, 0xf3, 0xf6, 0xc4, 0xf8, 0xcb, 0xfa, 0xef, 0xfc, 0x65, 0xff, + 0x05, 0x02, 0x7c, 0x04, 0xde, 0x06, 0x75, 0x09, 0x2b, 0x0c, 0x9b, 0x0e, + 0xf3, 0x10, 0xb3, 0x13, 0x3a, 0x16, 0xeb, 0x18, 0x55, 0x1c, 0xad, 0x1f, + 0xa8, 0x22, 0x54, 0x25, 0xae, 0x27, 0x33, 0x2a, 0x16, 0x2d, 0x36, 0x30, + 0x84, 0x33, 0x94, 0x36, 0xbd, 0x38, 0xa2, 0x3a, 0x7d, 0x3c, 0x06, 0x3e, + 0x24, 0x3f, 0x27, 0x40, 0x7c, 0x41, 0xef, 0x42, 0x14, 0x44, 0xeb, 0x44, + 0x06, 0x46, 0x53, 0x47, 0x47, 0x48, 0x9b, 0x48, 0xaf, 0x48, 0xd7, 0x48, + 0x4c, 0x49, 0xa0, 0x49, 0xbe, 0x49, 0xd4, 0x49, 0xfa, 0x49, 0x5e, 0x4a, + 0xcc, 0x4a, 0x14, 0x4b, 0xfe, 0x4a, 0x22, 0x4b, 0x10, 0x4c, 0x0c, 0x4d, + 0xb2, 0x4d, 0x4c, 0x4e, 0x3e, 0x4e, 0x77, 0x4d, 0x98, 0x4c, 0xf6, 0x4b, + 0x67, 0x4b, 0xf0, 0x4a, 0x2a, 0x4a, 0xea, 0x48, 0x06, 0x48, 0x47, 0x47, + 0xb2, 0x46, 0xda, 0x45, 0xad, 0x44, 0x5c, 0x43, 0x43, 0x42, 0x9e, 0x41, + 0x0a, 0x41, 0x49, 0x40, 0xa6, 0x3f, 0x9d, 0x3e, 0x3c, 0x3d, 0xc6, 0x3b, + 0xf6, 0x39, 0x87, 0x37, 0xf6, 0x34, 0x87, 0x32, 0x2b, 0x30, 0x6f, 0x2d, + 0xfa, 0x2a, 0x3d, 0x29, 0x48, 0x27, 0xc2, 0x24, 0x49, 0x22, 0xca, 0x1f, + 0xa0, 0x1c, 0x7c, 0x19, 0x06, 0x17, 0xbf, 0x14, 0x9f, 0x12, 0x96, 0x10, + 0xf9, 0x0d, 0x3e, 0x0b, 0xe8, 0x08, 0x5c, 0x06, 0xe7, 0x02, 0x6e, 0xff, + 0xca, 0xfc, 0x5b, 0xfa, 0xa0, 0xf7, 0xe9, 0xf4, 0x9c, 0xf2, 0x66, 0xf0, + 0xaf, 0xed, 0xfd, 0xea, 0xcc, 0xe8, 0x6e, 0xe6, 0x82, 0xe3, 0x97, 0xe0, + 0xed, 0xdd, 0x62, 0xdb, 0x7b, 0xd8, 0xd3, 0xd5, 0x5f, 0xd3, 0x1a, 0xd1, + 0x44, 0xcf, 0xeb, 0xcd, 0x89, 0xcc, 0xca, 0xca, 0x4d, 0xc9, 0x35, 0xc8, + 0x53, 0xc7, 0x0c, 0xc6, 0x06, 0xc4, 0xca, 0xc1, 0x09, 0xc0, 0x9c, 0xbe, + 0xa8, 0xbd, 0xfd, 0xbc, 0xf2, 0xbb, 0x9b, 0xba, 0x20, 0xb9, 0xe4, 0xb7, + 0xc1, 0xb6, 0xcd, 0xb5, 0x12, 0xb5, 0x55, 0xb4, 0xd1, 0xb3, 0x86, 0xb3, + 0x19, 0xb3, 0xe8, 0xb2, 0xd7, 0xb2, 0x72, 0xb2, 0x27, 0xb2, 0xb7, 0xb1, + 0x67, 0xb1, 0x65, 0xb1, 0xae, 0xb1, 0x6b, 0xb1, 0xf2, 0xb0, 0xeb, 0xb0, + 0x0f, 0xb1, 0xfe, 0xb0, 0xeb, 0xb0, 0xcf, 0xb0, 0x94, 0xb0, 0x3e, 0xb0, + 0x29, 0xb0, 0x56, 0xb0, 0x0c, 0xb0, 0xb7, 0xaf, 0xfb, 0xaf, 0x37, 0xb0, + 0x96, 0xb0, 0x42, 0xb1, 0xe8, 0xb1, 0xb5, 0xb2, 0xc5, 0xb3, 0x93, 0xb4, + 0x93, 0xb4, 0xee, 0xb4, 0x59, 0xb6, 0xca, 0xb7, 0x87, 0xb8, 0x6f, 0xb8, + 0x33, 0xb8, 0xaf, 0xb8, 0x4a, 0xb9, 0x9d, 0xb9, 0xf2, 0xb9, 0x48, 0xba, + 0xd0, 0xba, 0xe5, 0xbb, 0x4e, 0xbd, 0xaf, 0xbe, 0xe9, 0xbf, 0xba, 0xc1, + 0xc2, 0xc3, 0x73, 0xc5, 0xa6, 0xc6, 0x6a, 0xc7, 0x83, 0xc8, 0x42, 0xca, + 0xc8, 0xcb, 0x34, 0xcd, 0x94, 0xce, 0xcc, 0xcf, 0x31, 0xd1, 0x27, 0xd3, + 0x8c, 0xd5, 0x61, 0xd7, 0x78, 0xd9, 0x3b, 0xdc, 0x40, 0xdf, 0xdd, 0xe1, + 0x0c, 0xe4, 0xe4, 0xe5, 0xd0, 0xe7, 0x65, 0xea, 0xc9, 0xec, 0xd7, 0xee, + 0xfc, 0xf0, 0x7c, 0xf3, 0xf6, 0xf5, 0x09, 0xf8, 0xde, 0xf9, 0xca, 0xfb, + 0xac, 0xfd, 0xc3, 0xff, 0x33, 0x02, 0xb1, 0x04, 0x24, 0x07, 0x57, 0x09, + 0x5f, 0x0b, 0xe6, 0x0d, 0xd1, 0x10, 0x6d, 0x13, 0x8f, 0x15, 0xfb, 0x17, + 0x43, 0x1a, 0x8e, 0x1c, 0x1a, 0x1f, 0x69, 0x21, 0x80, 0x23, 0x74, 0x25, + 0x62, 0x27, 0x07, 0x29, 0xa1, 0x2a, 0xa5, 0x2c, 0xdf, 0x2e, 0x57, 0x31, + 0xff, 0x33, 0xd1, 0x36, 0x6e, 0x39, 0x8a, 0x3b, 0x58, 0x3d, 0x32, 0x3f, + 0xc8, 0x40, 0x1b, 0x42, 0x22, 0x43, 0x1a, 0x44, 0x25, 0x45, 0xe5, 0x45, + 0x43, 0x46, 0x9b, 0x46, 0x6a, 0x47, 0x6f, 0x48, 0x69, 0x49, 0x6f, 0x4a, + 0xc7, 0x4b, 0x0e, 0x4d, 0x03, 0x4e, 0x78, 0x4e, 0xdf, 0x4e, 0x0b, 0x4f, + 0xea, 0x4e, 0xcb, 0x4e, 0x1b, 0x4f, 0x6e, 0x4f, 0xc3, 0x4f, 0xdc, 0x4f, + 0xcb, 0x4f, 0xd2, 0x4f, 0x16, 0x50, 0x24, 0x50, 0xf2, 0x4f, 0x00, 0x50, + 0x37, 0x50, 0x4e, 0x50, 0x5e, 0x50, 0x7c, 0x50, 0xab, 0x50, 0x69, 0x50, + 0xad, 0x4f, 0xa3, 0x4e, 0xe6, 0x4d, 0x42, 0x4d, 0xdc, 0x4c, 0x7c, 0x4c, + 0xbe, 0x4b, 0x08, 0x4b, 0x7b, 0x4a, 0xe4, 0x49, 0x14, 0x49, 0x07, 0x48, + 0x98, 0x46, 0x2f, 0x45, 0x16, 0x44, 0x23, 0x43, 0x55, 0x42, 0xac, 0x41, + 0x06, 0x41, 0x4b, 0x40, 0x8f, 0x3f, 0xde, 0x3e, 0xe1, 0x3d, 0x75, 0x3c, + 0xc0, 0x3a, 0xe4, 0x38, 0x83, 0x37, 0x9a, 0x36, 0xe5, 0x35, 0xc0, 0x34, + 0xf9, 0x32, 0xe1, 0x30, 0xfa, 0x2e, 0xd4, 0x2c, 0x4d, 0x2a, 0xed, 0x27, + 0xb9, 0x25, 0xb2, 0x23, 0x7d, 0x21, 0xfd, 0x1e, 0x89, 0x1c, 0x38, 0x1a, + 0xe2, 0x17, 0x67, 0x15, 0xf3, 0x12, 0xb3, 0x10, 0x9e, 0x0e, 0x79, 0x0c, + 0xea, 0x09, 0x54, 0x07, 0x26, 0x05, 0x0a, 0x03, 0xd7, 0x00, 0x98, 0xfe, + 0x41, 0xfc, 0x8d, 0xf9, 0x3c, 0xf7, 0x4f, 0xf5, 0x73, 0xf3, 0x7b, 0xf1, + 0x68, 0xef, 0x6f, 0xed, 0x7a, 0xeb, 0x87, 0xe9, 0x48, 0xe7, 0xc6, 0xe4, + 0x65, 0xe2, 0xf6, 0xdf, 0x86, 0xdd, 0x9f, 0xdb, 0x1b, 0xda, 0xa6, 0xd8, + 0xce, 0xd6, 0xe4, 0xd4, 0xe3, 0xd2, 0x84, 0xd0, 0xec, 0xcd, 0x08, 0xcc, + 0x89, 0xca, 0x1b, 0xc9, 0xe2, 0xc7, 0x9d, 0xc6, 0xe5, 0xc4, 0x79, 0xc3, + 0x6d, 0xc2, 0xe3, 0xc0, 0x3c, 0xbf, 0xd3, 0xbd, 0x41, 0xbc, 0xd2, 0xba, + 0x6a, 0xb9, 0xa1, 0xb7, 0xa9, 0xb5, 0x47, 0xb4, 0x91, 0xb3, 0xd5, 0xb2, + 0xb7, 0xb1, 0x51, 0xb0, 0x14, 0xaf, 0xf5, 0xad, 0x95, 0xac, 0x34, 0xab, + 0x05, 0xaa, 0xe1, 0xa8, 0xb3, 0xa7, 0xd9, 0xa6, 0x25, 0xa6, 0x6e, 0xa5, + 0x2b, 0xa5, 0x7b, 0xa5, 0x9a, 0xa5, 0x88, 0xa5, 0xc3, 0xa5, 0xe7, 0xa5, + 0xaf, 0xa5, 0x8b, 0xa5, 0x80, 0xa5, 0x65, 0xa5, 0x8c, 0xa5, 0x7e, 0xa5, + 0x22, 0xa5, 0x40, 0xa5, 0xed, 0xa5, 0x27, 0xa6, 0x2b, 0xa6, 0x1c, 0xa6, + 0xe5, 0xa5, 0x7b, 0xa5, 0x45, 0xa5, 0x37, 0xa5, 0x04, 0xa5, 0x91, 0xa4, + 0x8d, 0xa4, 0x2d, 0xa5, 0x9f, 0xa5, 0xf6, 0xa5, 0x7e, 0xa6, 0x34, 0xa7, + 0x14, 0xa8, 0x7e, 0xa8, 0x87, 0xa8, 0xc4, 0xa8, 0x51, 0xa9, 0xec, 0xa9, + 0x74, 0xaa, 0xf7, 0xaa, 0x40, 0xab, 0xd9, 0xab, 0xca, 0xac, 0x6b, 0xad, + 0xb3, 0xad, 0x08, 0xae, 0x10, 0xaf, 0x2c, 0xb0, 0xcb, 0xb0, 0x23, 0xb1, + 0xac, 0xb1, 0x0e, 0xb2, 0x42, 0xb2, 0xd7, 0xb2, 0xef, 0xb3, 0x21, 0xb5, + 0x30, 0xb6, 0xe9, 0xb6, 0x54, 0xb7, 0xf0, 0xb7, 0x9e, 0xb8, 0x2e, 0xb9, + 0x03, 0xba, 0x55, 0xbb, 0xdf, 0xbc, 0x5f, 0xbe, 0xb8, 0xbf, 0x01, 0xc1, + 0x83, 0xc2, 0x0c, 0xc4, 0x65, 0xc5, 0x7e, 0xc6, 0x86, 0xc7, 0xba, 0xc8, + 0x11, 0xca, 0x66, 0xcb, 0x28, 0xcd, 0x4d, 0xcf, 0x60, 0xd1, 0x69, 0xd3, + 0x7b, 0xd5, 0x5f, 0xd7, 0xe3, 0xd8, 0xca, 0xda, 0xda, 0xdc, 0xda, 0xde, + 0xab, 0xe0, 0x59, 0xe2, 0x3b, 0xe4, 0x21, 0xe6, 0xfc, 0xe7, 0xcb, 0xe9, + 0xbe, 0xeb, 0x9c, 0xed, 0x47, 0xef, 0x0b, 0xf1, 0xd3, 0xf2, 0xbc, 0xf4, + 0x9c, 0xf6, 0x67, 0xf8, 0x2a, 0xfa, 0xc1, 0xfb, 0x7f, 0xfd, 0x41, 0xff, + 0x12, 0x01, 0xd2, 0x02, 0xfc, 0x04, 0xe8, 0x06, 0x9a, 0x08, 0x59, 0x0a, + 0x48, 0x0c, 0x36, 0x0e, 0x37, 0x10, 0x36, 0x12, 0x59, 0x14, 0x62, 0x16, + 0x86, 0x18, 0xb9, 0x1a, 0xc2, 0x1c, 0xcd, 0x1e, 0xf1, 0x20, 0x27, 0x23, + 0x7a, 0x25, 0xf9, 0x27, 0x2a, 0x2a, 0x1f, 0x2c, 0xf8, 0x2d, 0xa3, 0x2f, + 0x23, 0x31, 0xf4, 0x32, 0x2c, 0x35, 0x40, 0x37, 0x23, 0x39, 0xfe, 0x3a, + 0x11, 0x3d, 0x2c, 0x3f, 0xe8, 0x40, 0x8c, 0x42, 0x55, 0x44, 0x37, 0x46, + 0x99, 0x47, 0xcb, 0x48, 0x12, 0x4a, 0x60, 0x4b, 0x86, 0x4c, 0x9b, 0x4d, + 0xc8, 0x4e, 0xec, 0x4f, 0xe3, 0x50, 0x8a, 0x51, 0x23, 0x52, 0xd8, 0x52, + 0x68, 0x53, 0x9b, 0x53, 0xb1, 0x53, 0x11, 0x54, 0x94, 0x54, 0xf7, 0x54, + 0x4f, 0x55, 0xa4, 0x55, 0x03, 0x56, 0x51, 0x56, 0x92, 0x56, 0xfa, 0x56, + 0x59, 0x57, 0xad, 0x57, 0xcd, 0x57, 0xc5, 0x57, 0xa8, 0x57, 0x64, 0x57, + 0x49, 0x57, 0x63, 0x57, 0x64, 0x57, 0x40, 0x57, 0xf6, 0x56, 0xfc, 0x56, + 0x36, 0x57, 0x3b, 0x57, 0x1e, 0x57, 0x1c, 0x57, 0x03, 0x57, 0xee, 0x56, + 0xa5, 0x56, 0x80, 0x56, 0xd4, 0x56, 0xe4, 0x56, 0x92, 0x56, 0xf0, 0x55, + 0x02, 0x55, 0xab, 0x53, 0xb5, 0x52, 0x51, 0x52, 0x08, 0x52, 0x80, 0x51, + 0xb4, 0x50, 0xde, 0x4f, 0x27, 0x4f, 0x63, 0x4e, 0x58, 0x4d, 0x72, 0x4c, + 0x82, 0x4b, 0x81, 0x4a, 0x87, 0x49, 0xb4, 0x48, 0xb1, 0x47, 0x99, 0x46, + 0xb4, 0x45, 0x34, 0x45, 0xb8, 0x44, 0x2f, 0x44, 0x7f, 0x43, 0xa0, 0x42, + 0xcb, 0x41, 0xd1, 0x40, 0xeb, 0x3f, 0x28, 0x3f, 0x3d, 0x3e, 0x09, 0x3d, + 0x9d, 0x3b, 0x40, 0x3a, 0x1c, 0x39, 0xeb, 0x37, 0xd1, 0x36, 0xb3, 0x35, + 0x8b, 0x34, 0x0b, 0x33, 0x51, 0x31, 0xfb, 0x2f, 0xb9, 0x2e, 0x54, 0x2d, + 0xaf, 0x2b, 0xdf, 0x29, 0xf1, 0x27, 0x3a, 0x26, 0x6f, 0x24, 0x56, 0x22, + 0x20, 0x20, 0x0a, 0x1e, 0x3b, 0x1c, 0x55, 0x1a, 0x6c, 0x18, 0xaa, 0x16, + 0xef, 0x14, 0x0a, 0x13, 0x17, 0x11, 0x1c, 0x0f, 0x22, 0x0d, 0x46, 0x0b, + 0x53, 0x09, 0x46, 0x07, 0x46, 0x05, 0x4d, 0x03, 0x1a, 0x01, 0xd3, 0xfe, + 0x94, 0xfc, 0x8c, 0xfa, 0x8f, 0xf8, 0xc1, 0xf6, 0x27, 0xf5, 0x8f, 0xf3, + 0xf2, 0xf1, 0x74, 0xf0, 0xfa, 0xee, 0x4d, 0xed, 0x9e, 0xeb, 0xa2, 0xe9, + 0x73, 0xe7, 0xa9, 0xe5, 0x2d, 0xe4, 0xa3, 0xe2, 0xf9, 0xe0, 0x50, 0xdf, + 0xb9, 0xdd, 0x34, 0xdc, 0xad, 0xda, 0x0b, 0xd9, 0x77, 0xd7, 0xb9, 0xd5, + 0x37, 0xd4, 0xff, 0xd2, 0x8a, 0xd1, 0x14, 0xd0, 0xba, 0xce, 0x7d, 0xcd, + 0x2c, 0xcc, 0xa1, 0xca, 0x22, 0xc9, 0xa9, 0xc7, 0x0e, 0xc6, 0x66, 0xc4, + 0xfc, 0xc2, 0xa5, 0xc1, 0x4a, 0xc0, 0xff, 0xbe, 0xf7, 0xbd, 0x0e, 0xbd, + 0x1d, 0xbc, 0x16, 0xbb, 0xad, 0xb9, 0x44, 0xb8, 0xd7, 0xb6, 0x9e, 0xb5, + 0x9f, 0xb4, 0x97, 0xb3, 0x72, 0xb2, 0x5f, 0xb1, 0x67, 0xb0, 0x89, 0xaf, + 0x9d, 0xae, 0xbe, 0xad, 0x08, 0xad, 0x5d, 0xac, 0x8b, 0xab, 0xad, 0xaa, + 0xe4, 0xa9, 0x59, 0xa9, 0xc4, 0xa8, 0x02, 0xa8, 0x4d, 0xa7, 0xc2, 0xa6, + 0x4a, 0xa6, 0x09, 0xa6, 0xd2, 0xa5, 0x50, 0xa5, 0xec, 0xa4, 0xc2, 0xa4, + 0xd9, 0xa4, 0xbd, 0xa4, 0x97, 0xa4, 0xa5, 0xa4, 0xbf, 0xa4, 0xb4, 0xa4, + 0x8f, 0xa4, 0x31, 0xa4, 0x39, 0xa4, 0x7d, 0xa4, 0xab, 0xa4, 0xc7, 0xa4, + 0xb3, 0xa4, 0xab, 0xa4, 0xca, 0xa4, 0x05, 0xa5, 0x1e, 0xa5, 0x2a, 0xa5, + 0x2c, 0xa5, 0x18, 0xa5, 0x01, 0xa5, 0x33, 0xa5, 0x8c, 0xa5, 0xb2, 0xa5, + 0x81, 0xa5, 0x5c, 0xa5, 0x6e, 0xa5, 0x79, 0xa5, 0x4e, 0xa5, 0x17, 0xa5, + 0xff, 0xa4, 0x1c, 0xa5, 0x45, 0xa5, 0x8a, 0xa5, 0xbf, 0xa5, 0xdb, 0xa5, + 0x41, 0xa6, 0xfb, 0xa6, 0xc6, 0xa7, 0x86, 0xa8, 0x29, 0xa9, 0x97, 0xa9, + 0x27, 0xaa, 0xd7, 0xaa, 0x6d, 0xab, 0xf4, 0xab, 0x34, 0xac, 0x69, 0xac, + 0xc6, 0xac, 0x37, 0xad, 0xaa, 0xad, 0x34, 0xae, 0xd3, 0xae, 0x81, 0xaf, + 0x16, 0xb0, 0x72, 0xb0, 0xc8, 0xb0, 0x36, 0xb1, 0x91, 0xb1, 0xe0, 0xb1, + 0x3b, 0xb2, 0x8e, 0xb2, 0xe0, 0xb2, 0x2a, 0xb3, 0xab, 0xb3, 0x3a, 0xb4, + 0xf1, 0xb4, 0xc0, 0xb5, 0xae, 0xb6, 0x91, 0xb7, 0x82, 0xb8, 0x98, 0xb9, + 0x8f, 0xba, 0x88, 0xbb, 0x65, 0xbc, 0x20, 0xbd, 0xcb, 0xbd, 0xaf, 0xbe, + 0x94, 0xbf, 0x84, 0xc0, 0x85, 0xc1, 0x7b, 0xc2, 0x67, 0xc3, 0x66, 0xc4, + 0x7f, 0xc5, 0x89, 0xc6, 0x6b, 0xc7, 0x38, 0xc8, 0x29, 0xc9, 0x4a, 0xca, + 0x82, 0xcb, 0xc1, 0xcc, 0x12, 0xce, 0x5e, 0xcf, 0xb0, 0xd0, 0x25, 0xd2, + 0x66, 0xd3, 0xde, 0xd4, 0x6c, 0xd6, 0x28, 0xd8, 0xd7, 0xd9, 0x80, 0xdb, + 0xf7, 0xdc, 0x6f, 0xde, 0xd0, 0xdf, 0x22, 0xe1, 0x7a, 0xe2, 0xe5, 0xe3, + 0x7a, 0xe5, 0xea, 0xe6, 0x51, 0xe8, 0xeb, 0xe9, 0x70, 0xeb, 0xb3, 0xec, + 0x01, 0xee, 0x60, 0xef, 0xcb, 0xf0, 0x1d, 0xf2, 0x7b, 0xf3, 0xcf, 0xf4, + 0x39, 0xf6, 0xc8, 0xf7, 0x82, 0xf9, 0x4a, 0xfb, 0xf2, 0xfc, 0x8c, 0xfe, + 0x01, 0x00, 0x68, 0x01, 0x15, 0x03, 0xe6, 0x04, 0xbc, 0x06, 0x42, 0x08, + 0xbb, 0x09, 0x2b, 0x0b, 0xc7, 0x0c, 0x35, 0x0e, 0x94, 0x0f, 0xf2, 0x10, + 0x59, 0x12, 0xbc, 0x13, 0x34, 0x15, 0xac, 0x16, 0x1c, 0x18, 0x79, 0x19, + 0xdc, 0x1a, 0x6d, 0x1c, 0x21, 0x1e, 0xca, 0x1f, 0x70, 0x21, 0x02, 0x23, + 0x6c, 0x24, 0x9e, 0x25, 0x45, 0x27, 0x02, 0x29, 0x95, 0x2a, 0xff, 0x2b, + 0x72, 0x2d, 0xe8, 0x2e, 0x48, 0x30, 0x7c, 0x31, 0xd2, 0x32, 0x3d, 0x34, + 0xac, 0x35, 0x26, 0x37, 0xbc, 0x38, 0x4c, 0x3a, 0x90, 0x3b, 0xef, 0x3c, + 0x61, 0x3e, 0xe8, 0x3f, 0x59, 0x41, 0xab, 0x42, 0xf7, 0x43, 0x2d, 0x45, + 0x6c, 0x46, 0x78, 0x47, 0xb4, 0x48, 0x2e, 0x4a, 0x8e, 0x4b, 0xd7, 0x4c, + 0xf4, 0x4d, 0xee, 0x4e, 0xcb, 0x4f, 0xc3, 0x50, 0xc2, 0x51, 0xac, 0x52, + 0x61, 0x53, 0xf3, 0x53, 0xac, 0x54, 0x5f, 0x55, 0xf4, 0x55, 0x7f, 0x56, + 0x04, 0x57, 0x9c, 0x57, 0x1f, 0x58, 0x7c, 0x58, 0xbc, 0x58, 0x0b, 0x59, + 0x71, 0x59, 0xc1, 0x59, 0x0b, 0x5a, 0x3e, 0x5a, 0x8b, 0x5a, 0xac, 0x5a, + 0xa9, 0x5a, 0x8a, 0x5a, 0x6c, 0x5a, 0x4c, 0x5a, 0x39, 0x5a, 0x32, 0x5a, + 0x40, 0x5a, 0x33, 0x5a, 0x44, 0x5a, 0x58, 0x5a, 0x79, 0x5a, 0x7a, 0x5a, + 0x69, 0x5a, 0x49, 0x5a, 0x54, 0x5a, 0x78, 0x5a, 0x72, 0x5a, 0x5f, 0x5a, + 0x31, 0x5a, 0x11, 0x5a, 0xf9, 0x59, 0xea, 0x59, 0xd1, 0x59, 0xa1, 0x59, + 0x48, 0x59, 0xf0, 0x58, 0xa2, 0x58, 0x6e, 0x58, 0x60, 0x58, 0x46, 0x58, + 0x3f, 0x58, 0x47, 0x58, 0x40, 0x58, 0x08, 0x58, 0x9c, 0x57, 0x11, 0x57, + 0x83, 0x56, 0xd7, 0x55, 0x42, 0x55, 0xab, 0x54, 0x06, 0x54, 0x63, 0x53, + 0xa6, 0x52, 0xf0, 0x51, 0x55, 0x51, 0xbc, 0x50, 0x1e, 0x50, 0x8e, 0x4f, + 0xf3, 0x4e, 0x34, 0x4e, 0x6b, 0x4d, 0xc9, 0x4c, 0x30, 0x4c, 0x7d, 0x4b, + 0xd8, 0x4a, 0x49, 0x4a, 0xad, 0x49, 0x11, 0x49, 0x6c, 0x48, 0xa4, 0x47, + 0xec, 0x46, 0x6c, 0x46, 0xde, 0x45, 0x5d, 0x45, 0xbc, 0x44, 0xf1, 0x43, + 0x34, 0x43, 0x8c, 0x42, 0xf8, 0x41, 0x47, 0x41, 0x6a, 0x40, 0x72, 0x3f, + 0x8b, 0x3e, 0xb3, 0x3d, 0xf2, 0x3c, 0x2f, 0x3c, 0x5c, 0x3b, 0x96, 0x3a, + 0xbc, 0x39, 0xb2, 0x38, 0x91, 0x37, 0x8c, 0x36, 0x75, 0x35, 0x63, 0x34, + 0x5e, 0x33, 0x63, 0x32, 0x4b, 0x31, 0x3c, 0x30, 0x1e, 0x2f, 0x07, 0x2e, + 0xd0, 0x2c, 0xb2, 0x2b, 0x84, 0x2a, 0x4d, 0x29, 0xfc, 0x27, 0xa5, 0x26, + 0x2f, 0x25, 0x95, 0x23, 0x1f, 0x22, 0xad, 0x20, 0x3a, 0x1f, 0x9e, 0x1d, + 0x10, 0x1c, 0x6e, 0x1a, 0xe3, 0x18, 0x56, 0x17, 0xdb, 0x15, 0x58, 0x14, + 0xba, 0x12, 0x2a, 0x11, 0x8b, 0x0f, 0xf4, 0x0d, 0x5b, 0x0c, 0xd3, 0x0a, + 0x5f, 0x09, 0xe5, 0x07, 0x4a, 0x06, 0xc0, 0x04, 0x3e, 0x03, 0xb6, 0x01, + 0x37, 0x00, 0xca, 0xfe, 0x74, 0xfd, 0x00, 0xfc, 0xa5, 0xfa, 0x4a, 0xf9, + 0xd1, 0xf7, 0x7e, 0xf6, 0x1c, 0xf5, 0x9d, 0xf3, 0x4f, 0xf2, 0x0e, 0xf1, + 0xc0, 0xef, 0x3a, 0xee, 0xd8, 0xec, 0x69, 0xeb, 0x0c, 0xea, 0xad, 0xe8, + 0x56, 0xe7, 0xf8, 0xe5, 0xbe, 0xe4, 0x98, 0xe3, 0x61, 0xe2, 0x03, 0xe1, + 0x99, 0xdf, 0x4d, 0xde, 0x0e, 0xdd, 0xde, 0xdb, 0xad, 0xda, 0x84, 0xd9, + 0x62, 0xd8, 0x32, 0xd7, 0x01, 0xd6, 0xb7, 0xd4, 0x87, 0xd3, 0x97, 0xd2, + 0x89, 0xd1, 0x89, 0xd0, 0x6e, 0xcf, 0x65, 0xce, 0x5d, 0xcd, 0x44, 0xcc, + 0x13, 0xcb, 0xf2, 0xc9, 0xd3, 0xc8, 0xad, 0xc7, 0x9b, 0xc6, 0x94, 0xc5, + 0x8e, 0xc4, 0x7b, 0xc3, 0x92, 0xc2, 0xad, 0xc1, 0xb2, 0xc0, 0xb9, 0xbf, + 0xb3, 0xbe, 0xc0, 0xbd, 0xd5, 0xbc, 0xf2, 0xbb, 0xe1, 0xba, 0xc7, 0xb9, + 0xc7, 0xb8, 0xe8, 0xb7, 0x09, 0xb7, 0x2c, 0xb6, 0x66, 0xb5, 0xb1, 0xb4, + 0xf6, 0xb3, 0x32, 0xb3, 0x53, 0xb2, 0x92, 0xb1, 0xdb, 0xb0, 0x0d, 0xb0, + 0x46, 0xaf, 0x62, 0xae, 0x98, 0xad, 0xd1, 0xac, 0x3f, 0xac, 0xb0, 0xab, + 0x34, 0xab, 0xb1, 0xaa, 0x45, 0xaa, 0xda, 0xa9, 0x6a, 0xa9, 0xf1, 0xa8, + 0x7d, 0xa8, 0x04, 0xa8, 0xbb, 0xa7, 0x80, 0xa7, 0x41, 0xa7, 0x02, 0xa7, + 0xb6, 0xa6, 0x68, 0xa6, 0x3b, 0xa6, 0x1c, 0xa6, 0x0d, 0xa6, 0xfc, 0xa5, + 0xd4, 0xa5, 0xa6, 0xa5, 0x81, 0xa5, 0x76, 0xa5, 0x61, 0xa5, 0x54, 0xa5, + 0x48, 0xa5, 0x47, 0xa5, 0x4b, 0xa5, 0x49, 0xa5, 0x38, 0xa5, 0x4b, 0xa5, + 0x6c, 0xa5, 0xa3, 0xa5, 0xda, 0xa5, 0xfe, 0xa5, 0x21, 0xa6, 0x4a, 0xa6, + 0x8a, 0xa6, 0xb4, 0xa6, 0xe0, 0xa6, 0xf3, 0xa6, 0x1b, 0xa7, 0x17, 0xa7, + 0x40, 0xa7, 0x8e, 0xa7, 0xcd, 0xa7, 0x06, 0xa8, 0x3e, 0xa8, 0x86, 0xa8, + 0xbd, 0xa8, 0xde, 0xa8, 0xf6, 0xa8, 0x1c, 0xa9, 0x49, 0xa9, 0x5c, 0xa9, + 0x79, 0xa9, 0x93, 0xa9, 0xab, 0xa9, 0xe6, 0xa9, 0x2c, 0xaa, 0x82, 0xaa, + 0xbc, 0xaa, 0xec, 0xaa, 0x32, 0xab, 0x69, 0xab, 0xa7, 0xab, 0xde, 0xab, + 0x19, 0xac, 0x53, 0xac, 0xbb, 0xac, 0x14, 0xad, 0x8a, 0xad, 0xeb, 0xad, + 0x6c, 0xae, 0xe1, 0xae, 0x62, 0xaf, 0xd9, 0xaf, 0x58, 0xb0, 0xc0, 0xb0, + 0x36, 0xb1, 0x99, 0xb1, 0x11, 0xb2, 0x71, 0xb2, 0xdc, 0xb2, 0x58, 0xb3, + 0xbb, 0xb3, 0x37, 0xb4, 0xb6, 0xb4, 0x46, 0xb5, 0xca, 0xb5, 0x50, 0xb6, + 0xd9, 0xb6, 0x6c, 0xb7, 0x03, 0xb8, 0x7e, 0xb8, 0xf0, 0xb8, 0x64, 0xb9, + 0xcf, 0xb9, 0x47, 0xba, 0xd3, 0xba, 0x60, 0xbb, 0xe8, 0xbb, 0x70, 0xbc, + 0xf3, 0xbc, 0x82, 0xbd, 0x05, 0xbe, 0xa1, 0xbe, 0x2a, 0xbf, 0xae, 0xbf, + 0x25, 0xc0, 0xac, 0xc0, 0x52, 0xc1, 0xde, 0xc1, 0x75, 0xc2, 0x11, 0xc3, + 0xb5, 0xc3, 0x42, 0xc4, 0xc5, 0xc4, 0x6d, 0xc5, 0x0b, 0xc6, 0xb2, 0xc6, + 0x4b, 0xc7, 0xf6, 0xc7, 0x9b, 0xc8, 0x4f, 0xc9, 0x17, 0xca, 0xf3, 0xca, + 0xc6, 0xcb, 0x9a, 0xcc, 0x7b, 0xcd, 0x54, 0xce, 0x32, 0xcf, 0x09, 0xd0, + 0xd7, 0xd0, 0xc9, 0xd1, 0xc1, 0xd2, 0xb8, 0xd3, 0xb6, 0xd4, 0xae, 0xd5, + 0xbc, 0xd6, 0xca, 0xd7, 0xd2, 0xd8, 0xca, 0xd9, 0xbd, 0xda, 0xc8, 0xdb, + 0xd8, 0xdc, 0xf9, 0xdd, 0x08, 0xdf, 0x1e, 0xe0, 0x39, 0xe1, 0x4e, 0xe2, + 0x60, 0xe3, 0x7a, 0xe4, 0x96, 0xe5, 0xc1, 0xe6, 0xde, 0xe7, 0x0e, 0xe9, + 0x2a, 0xea, 0x42, 0xeb, 0x7a, 0xec, 0x9f, 0xed, 0xbb, 0xee, 0xd6, 0xef, + 0xef, 0xf0, 0x0e, 0xf2, 0x30, 0xf3, 0x55, 0xf4, 0x68, 0xf5, 0x7e, 0xf6, + 0xa4, 0xf7, 0xc0, 0xf8, 0xea, 0xf9, 0x10, 0xfb, 0x41, 0xfc, 0x7d, 0xfd, + 0xad, 0xfe, 0xe3, 0xff, 0x10, 0x01, 0x27, 0x02, 0x58, 0x03, 0x74, 0x04, + 0xa4, 0x05, 0xd5, 0x06, 0x0b, 0x08, 0x36, 0x09, 0x5c, 0x0a, 0x76, 0x0b, + 0x9a, 0x0c, 0xc1, 0x0d, 0xd8, 0x0e, 0xf5, 0x0f, 0x15, 0x11, 0x3f, 0x12, + 0x70, 0x13, 0x8e, 0x14, 0xcc, 0x15, 0xf2, 0x16, 0x31, 0x18, 0x4b, 0x19, + 0x82, 0x1a, 0xa1, 0x1b, 0xbc, 0x1c, 0xde, 0x1d, 0xe9, 0x1e, 0x13, 0x20, + 0x33, 0x21, 0x6c, 0x22, 0x80, 0x23, 0xa7, 0x24, 0xbc, 0x25, 0xde, 0x26, + 0xe7, 0x27, 0x07, 0x29, 0x28, 0x2a, 0x36, 0x2b, 0x4d, 0x2c, 0x71, 0x2d, + 0x91, 0x2e, 0xbe, 0x2f, 0xd6, 0x30, 0xfb, 0x31, 0x20, 0x33, 0x46, 0x34, + 0x59, 0x35, 0x7a, 0x36, 0xa1, 0x37, 0xc2, 0x38, 0xdf, 0x39, 0x01, 0x3b, + 0x0f, 0x3c, 0x27, 0x3d, 0x1f, 0x3e, 0x2e, 0x3f, 0x43, 0x40, 0x5b, 0x41, + 0x73, 0x42, 0x8e, 0x43, 0xaf, 0x44, 0xbc, 0x45, 0xcc, 0x46, 0xd8, 0x47, + 0xec, 0x48, 0xe1, 0x49, 0xd1, 0x4a, 0xc4, 0x4b, 0xb6, 0x4c, 0xa9, 0x4d, + 0x9d, 0x4e, 0x88, 0x4f, 0x75, 0x50, 0x4c, 0x51, 0x3b, 0x52, 0x05, 0x53, + 0xd9, 0x53, 0xa1, 0x54, 0x6f, 0x55, 0x33, 0x56, 0xe5, 0x56, 0x7d, 0x57, + 0x15, 0x58, 0xb3, 0x58, 0x4e, 0x59, 0xdb, 0x59, 0x55, 0x5a, 0xc8, 0x5a, + 0x36, 0x5b, 0xa9, 0x5b, 0x09, 0x5c, 0x5a, 0x5c, 0xab, 0x5c, 0xf1, 0x5c, + 0x34, 0x5d, 0x6a, 0x5d, 0x9e, 0x5d, 0xc1, 0x5d, 0xea, 0x5d, 0x0b, 0x5e, + 0x28, 0x5e, 0x3d, 0x5e, 0x41, 0x5e, 0x51, 0x5e, 0x5f, 0x5e, 0x69, 0x5e, + 0x79, 0x5e, 0x6a, 0x5e, 0x78, 0x5e, 0x76, 0x5e, 0x7f, 0x5e, 0x72, 0x5e, + 0x70, 0x5e, 0x61, 0x5e, 0x61, 0x5e, 0x42, 0x5e, 0x36, 0x5e, 0x2f, 0x5e, + 0x2c, 0x5e, 0x1a, 0x5e, 0xec, 0x5d, 0xbf, 0x5d, 0x94, 0x5d, 0x71, 0x5d, + 0x4c, 0x5d, 0x24, 0x5d, 0xfa, 0x5c, 0xc3, 0x5c, 0x8c, 0x5c, 0x59, 0x5c, + 0x3e, 0x5c, 0x0c, 0x5c, 0xd3, 0x5b, 0xb1, 0x5b, 0x78, 0x5b, 0x45, 0x5b, + 0x14, 0x5b, 0xed, 0x5a, 0xc0, 0x5a, 0x89, 0x5a, 0x4f, 0x5a, 0x16, 0x5a, + 0xe5, 0x59, 0xb5, 0x59, 0x84, 0x59, 0x4e, 0x59, 0x0d, 0x59, 0xcf, 0x58, + 0xa6, 0x58, 0x79, 0x58, 0x3e, 0x58, 0xf8, 0x57, 0xc0, 0x57, 0x83, 0x57, + 0x38, 0x57, 0x03, 0x57, 0xc1, 0x56, 0x65, 0x56, 0xe0, 0x55, 0x52, 0x55, + 0xd0, 0x54, 0x4c, 0x54, 0xbe, 0x53, 0x32, 0x53, 0xa7, 0x52, 0x2a, 0x52, + 0x95, 0x51, 0x09, 0x51, 0x76, 0x50, 0xe9, 0x4f, 0x69, 0x4f, 0xe2, 0x4e, + 0x49, 0x4e, 0xc0, 0x4d, 0x38, 0x4d, 0xbd, 0x4c, 0x2d, 0x4c, 0x98, 0x4b, + 0x07, 0x4b, 0x76, 0x4a, 0xdc, 0x49, 0x4a, 0x49, 0xb9, 0x48, 0x2d, 0x48, + 0x9c, 0x47, 0x19, 0x47, 0x80, 0x46, 0xf9, 0x45, 0x66, 0x45, 0xd6, 0x44, + 0x47, 0x44, 0xb5, 0x43, 0x14, 0x43, 0x74, 0x42, 0xd4, 0x41, 0x42, 0x41, + 0xa4, 0x40, 0x18, 0x40, 0x85, 0x3f, 0xeb, 0x3e, 0x52, 0x3e, 0xb2, 0x3d, + 0x0c, 0x3d, 0x7a, 0x3c, 0xdb, 0x3b, 0x3a, 0x3b, 0x87, 0x3a, 0xe0, 0x39, + 0x29, 0x39, 0x88, 0x38, 0xd1, 0x37, 0x16, 0x37, 0x4d, 0x36, 0x9e, 0x35, + 0xdc, 0x34, 0x19, 0x34, 0x4a, 0x33, 0x83, 0x32, 0xb7, 0x31, 0xec, 0x30, + 0x1c, 0x30, 0x47, 0x2f, 0x71, 0x2e, 0x88, 0x2d, 0xa6, 0x2c, 0xbb, 0x2b, + 0xd0, 0x2a, 0xd8, 0x29, 0xdb, 0x28, 0xe3, 0x27, 0xf5, 0x26, 0xf1, 0x25, + 0xf8, 0x24, 0xdc, 0x23, 0xdb, 0x22, 0xca, 0x21, 0xa7, 0x20, 0x85, 0x1f, + 0x5a, 0x1e, 0x30, 0x1d, 0x0a, 0x1c, 0xd5, 0x1a, 0xa6, 0x19, 0x6d, 0x18, + 0x3d, 0x17, 0xff, 0x15, 0xbf, 0x14, 0x81, 0x13, 0x57, 0x12, 0x15, 0x11, + 0xe0, 0x0f, 0xa2, 0x0e, 0x65, 0x0d, 0x27, 0x0c, 0xf1, 0x0a, 0xb2, 0x09, + 0x77, 0x08, 0x4b, 0x07, 0x0a, 0x06, 0xc9, 0x04, 0x97, 0x03, 0x65, 0x02, + 0x3b, 0x01, 0x03, 0x00, 0xd2, 0xfe, 0x95, 0xfd, 0x6f, 0xfc, 0x50, 0xfb, + 0x19, 0xfa, 0xf0, 0xf8, 0xb8, 0xf7, 0x97, 0xf6, 0x65, 0xf5, 0x48, 0xf4, + 0x24, 0xf3, 0xfe, 0xf1, 0xec, 0xf0, 0xd2, 0xef, 0xa9, 0xee, 0x95, 0xed, + 0x76, 0xec, 0x64, 0xeb, 0x61, 0xea, 0x43, 0xe9, 0x3a, 0xe8, 0x21, 0xe7, + 0x14, 0xe6, 0xff, 0xe4, 0x06, 0xe4, 0x04, 0xe3, 0x04, 0xe2, 0x01, 0xe1, + 0x02, 0xe0, 0x04, 0xdf, 0x16, 0xde, 0x1f, 0xdd, 0x29, 0xdc, 0x2d, 0xdb, + 0x3d, 0xda, 0x45, 0xd9, 0x5a, 0xd8, 0x6f, 0xd7, 0x74, 0xd6, 0x8a, 0xd5, + 0x91, 0xd4, 0xa5, 0xd3, 0xbb, 0xd2, 0xdb, 0xd1, 0x01, 0xd1, 0x17, 0xd0, + 0x42, 0xcf, 0x5e, 0xce, 0x94, 0xcd, 0xb1, 0xcc, 0xe8, 0xcb, 0x04, 0xcb, + 0x29, 0xca, 0x4e, 0xc9, 0x78, 0xc8, 0x99, 0xc7, 0xc4, 0xc6, 0xff, 0xc5, + 0x3d, 0xc5, 0x76, 0xc4, 0xa6, 0xc3, 0xe4, 0xc2, 0x17, 0xc2, 0x4e, 0xc1, + 0x8a, 0xc0, 0xc5, 0xbf, 0x0b, 0xbf, 0x42, 0xbe, 0x8e, 0xbd, 0xd8, 0xbc, + 0x20, 0xbc, 0x60, 0xbb, 0xbb, 0xba, 0x08, 0xba, 0x5a, 0xb9, 0xba, 0xb8, + 0x08, 0xb8, 0x64, 0xb7, 0xb1, 0xb6, 0x0c, 0xb6, 0x5d, 0xb5, 0xbf, 0xb4, + 0x10, 0xb4, 0x7b, 0xb3, 0xd0, 0xb2, 0x3d, 0xb2, 0xa1, 0xb1, 0x0f, 0xb1, + 0x84, 0xb0, 0xf2, 0xaf, 0x63, 0xaf, 0xd3, 0xae, 0x50, 0xae, 0xbd, 0xad, + 0x49, 0xad, 0xc1, 0xac, 0x4d, 0xac, 0xc6, 0xab, 0x56, 0xab, 0xe4, 0xaa, + 0x83, 0xaa, 0x0d, 0xaa, 0xac, 0xa9, 0x49, 0xa9, 0xf3, 0xa8, 0x9e, 0xa8, + 0x4e, 0xa8, 0x07, 0xa8, 0xc5, 0xa7, 0x8d, 0xa7, 0x56, 0xa7, 0x1d, 0xa7, + 0xf6, 0xa6, 0xc7, 0xa6, 0xad, 0xa6, 0x8c, 0xa6, 0x74, 0xa6, 0x58, 0xa6, + 0x47, 0xa6, 0x2d, 0xa6, 0x24, 0xa6, 0x23, 0xa6, 0x21, 0xa6, 0x19, 0xa6, + 0x20, 0xa6, 0x1f, 0xa6, 0x28, 0xa6, 0x3c, 0xa6, 0x4e, 0xa6, 0x59, 0xa6, + 0x6e, 0xa6, 0x84, 0xa6, 0x9a, 0xa6, 0xb7, 0xa6, 0xd4, 0xa6, 0xef, 0xa6, + 0x0a, 0xa7, 0x2f, 0xa7, 0x53, 0xa7, 0x77, 0xa7, 0x9c, 0xa7, 0xbc, 0xa7, + 0xe5, 0xa7, 0x10, 0xa8, 0x35, 0xa8, 0x6d, 0xa8, 0x9b, 0xa8, 0xcb, 0xa8, + 0xf5, 0xa8, 0x23, 0xa9, 0x5a, 0xa9, 0x80, 0xa9, 0xb7, 0xa9, 0xee, 0xa9, + 0x1c, 0xaa, 0x46, 0xaa, 0x78, 0xaa, 0xb2, 0xaa, 0xeb, 0xaa, 0x1a, 0xab, + 0x57, 0xab, 0x84, 0xab, 0xba, 0xab, 0xef, 0xab, 0x22, 0xac, 0x55, 0xac, + 0x88, 0xac, 0xc1, 0xac, 0xf5, 0xac, 0x2a, 0xad, 0x67, 0xad, 0x9f, 0xad, + 0xe0, 0xad, 0x14, 0xae, 0x4c, 0xae, 0x82, 0xae, 0xb8, 0xae, 0xf8, 0xae, + 0x2c, 0xaf, 0x6a, 0xaf, 0x9d, 0xaf, 0xd4, 0xaf, 0x05, 0xb0, 0x38, 0xb0, + 0x77, 0xb0, 0xb2, 0xb0, 0xf8, 0xb0, 0x3c, 0xb1, 0x97, 0xb1, 0x05, 0xb2, + 0x6f, 0xb2, 0xdf, 0xb2, 0x48, 0xb3, 0xb2, 0xb3, 0x16, 0xb4, 0x7b, 0xb4, + 0xe5, 0xb4, 0x54, 0xb5, 0xc3, 0xb5, 0x26, 0xb6, 0x97, 0xb6, 0x03, 0xb7, + 0x68, 0xb7, 0xce, 0xb7, 0x44, 0xb8, 0xae, 0xb8, 0x20, 0xb9, 0x87, 0xb9, + 0xf1, 0xb9, 0x5d, 0xba, 0xc6, 0xba, 0x24, 0xbb, 0xa1, 0xbb, 0x05, 0xbc, + 0x79, 0xbc, 0xdc, 0xbc, 0x4b, 0xbd, 0xba, 0xbd, 0x24, 0xbe, 0x9b, 0xbe, + 0x07, 0xbf, 0x72, 0xbf, 0xe5, 0xbf, 0x46, 0xc0, 0xc3, 0xc0, 0x1f, 0xc1, + 0x91, 0xc1, 0x01, 0xc2, 0x79, 0xc2, 0xf1, 0xc2, 0x66, 0xc3, 0xe5, 0xc3, + 0x55, 0xc4, 0xc8, 0xc4, 0x3e, 0xc5, 0xb3, 0xc5, 0x2d, 0xc6, 0xa7, 0xc6, + 0x27, 0xc7, 0x97, 0xc7, 0x1f, 0xc8, 0xa0, 0xc8, 0x29, 0xc9, 0xad, 0xc9, + 0x36, 0xca, 0xad, 0xca, 0x3d, 0xcb, 0xc0, 0xcb, 0x47, 0xcc, 0xe9, 0xcc, + 0x6f, 0xcd, 0x06, 0xce, 0x84, 0xce, 0x1a, 0xcf, 0xbb, 0xcf, 0x55, 0xd0, + 0xf6, 0xd0, 0x8b, 0xd1, 0x30, 0xd2, 0xd2, 0xd2, 0x79, 0xd3, 0x1c, 0xd4, + 0xcf, 0xd4, 0x83, 0xd5, 0x36, 0xd6, 0xe1, 0xd6, 0x96, 0xd7, 0x5f, 0xd8, + 0x1c, 0xd9, 0xe2, 0xd9, 0xa8, 0xda, 0x6c, 0xdb, 0x43, 0xdc, 0x04, 0xdd, + 0xd8, 0xdd, 0xac, 0xde, 0x8a, 0xdf, 0x5b, 0xe0, 0x39, 0xe1, 0x0b, 0xe2, + 0xf5, 0xe2, 0xde, 0xe3, 0xbc, 0xe4, 0x9e, 0xe5, 0x83, 0xe6, 0x62, 0xe7, + 0x51, 0xe8, 0x34, 0xe9, 0x1e, 0xea, 0x12, 0xeb, 0xf7, 0xeb, 0xe5, 0xec, + 0xc5, 0xed, 0xc2, 0xee, 0xb1, 0xef, 0xa6, 0xf0, 0x90, 0xf1, 0x7e, 0xf2, + 0x6f, 0xf3, 0x56, 0xf4, 0x48, 0xf5, 0x35, 0xf6, 0x29, 0xf7, 0x17, 0xf8, + 0x0a, 0xf9, 0x00, 0xfa, 0xe7, 0xfa, 0xde, 0xfb, 0xc9, 0xfc, 0xc1, 0xfd, + 0xac, 0xfe, 0xae, 0xff, 0xa2, 0x00, 0x8d, 0x01, 0x70, 0x02, 0x62, 0x03, + 0x4e, 0x04, 0x3a, 0x05, 0x26, 0x06, 0x16, 0x07, 0xff, 0x07, 0xf3, 0x08, + 0xda, 0x09, 0xbe, 0x0a, 0xb9, 0x0b, 0xa1, 0x0c, 0x9b, 0x0d, 0x7d, 0x0e, + 0x66, 0x0f, 0x54, 0x10, 0x36, 0x11, 0x20, 0x12, 0x11, 0x13, 0xf3, 0x13, + 0xea, 0x14, 0xd1, 0x15, 0xb6, 0x16, 0x9b, 0x17, 0x83, 0x18, 0x7f, 0x19, + 0x58, 0x1a, 0x53, 0x1b, 0x37, 0x1c, 0x22, 0x1d, 0x0a, 0x1e, 0xf3, 0x1e, + 0xda, 0x1f, 0xca, 0x20, 0xb1, 0x21, 0x96, 0x22, 0x70, 0x23, 0x55, 0x24, + 0x39, 0x25, 0x39, 0x26, 0x1a, 0x27, 0x07, 0x28, 0xe1, 0x28, 0xc5, 0x29, + 0xa7, 0x2a, 0x85, 0x2b, 0x70, 0x2c, 0x4e, 0x2d, 0x3e, 0x2e, 0x19, 0x2f, + 0xf3, 0x2f, 0xdf, 0x30, 0xc0, 0x31, 0xaf, 0x32, 0x93, 0x33, 0x77, 0x34, + 0x48, 0x35, 0x2a, 0x36, 0x0f, 0x37, 0xf8, 0x37, 0xd9, 0x38, 0xbe, 0x39, + 0x8b, 0x3a, 0x74, 0x3b, 0x48, 0x3c, 0x2d, 0x3d, 0xfa, 0x3d, 0xe7, 0x3e, + 0xb0, 0x3f, 0x98, 0x40, 0x67, 0x41, 0x3a, 0x42, 0x16, 0x43, 0xf4, 0x43, + 0xd8, 0x44, 0xa4, 0x45, 0x7c, 0x46, 0x4c, 0x47, 0x2a, 0x48, 0x06, 0x49, + 0xce, 0x49, 0xa5, 0x4a, 0x77, 0x4b, 0x4e, 0x4c, 0x13, 0x4d, 0xdf, 0x4d, + 0xaa, 0x4e, 0x74, 0x4f, 0x3d, 0x50, 0xfc, 0x50, 0xbd, 0x51, 0x8c, 0x52, + 0x3e, 0x53, 0xfe, 0x53, 0x99, 0x54, 0x57, 0x55, 0xfc, 0x55, 0xab, 0x56, + 0x45, 0x57, 0xd6, 0x57, 0x87, 0x58, 0x2f, 0x59, 0xbf, 0x59, 0x48, 0x5a, + 0xc7, 0x5a, 0x54, 0x5b, 0xc8, 0x5b, 0x45, 0x5c, 0xb4, 0x5c, 0x25, 0x5d, + 0x7e, 0x5d, 0xda, 0x5d, 0x36, 0x5e, 0xa5, 0x5e, 0xe9, 0x5e, 0x37, 0x5f, + 0x72, 0x5f, 0xab, 0x5f, 0xe5, 0x5f, 0x1d, 0x60, 0x4f, 0x60, 0x81, 0x60, + 0x9c, 0x60, 0xc3, 0x60, 0xdc, 0x60, 0xf7, 0x60, 0x04, 0x61, 0x16, 0x61, + 0x1b, 0x61, 0x21, 0x61, 0x20, 0x61, 0x0d, 0x61, 0x0b, 0x61, 0xf0, 0x60, + 0xe5, 0x60, 0xc7, 0x60, 0xb3, 0x60, 0x98, 0x60, 0x7c, 0x60, 0x59, 0x60, + 0x4c, 0x60, 0x24, 0x60, 0x0d, 0x60, 0xdf, 0x5f, 0xb7, 0x5f, 0x87, 0x5f, + 0x6b, 0x5f, 0x44, 0x5f, 0x28, 0x5f, 0xf5, 0x5e, 0xbd, 0x5e, 0x8f, 0x5e, + 0x5c, 0x5e, 0x2a, 0x5e, 0xfe, 0x5d, 0xcd, 0x5d, 0xa4, 0x5d, 0x75, 0x5d, + 0x4d, 0x5d, 0x11, 0x5d, 0xdf, 0x5c, 0xa9, 0x5c, 0x78, 0x5c, 0x42, 0x5c, + 0x13, 0x5c, 0xde, 0x5b, 0xaf, 0x5b, 0x75, 0x5b, 0x3e, 0x5b, 0xfd, 0x5a, + 0xbc, 0x5a, 0x90, 0x5a, 0x54, 0x5a, 0x1f, 0x5a, 0xe5, 0x59, 0xc2, 0x59, + 0x80, 0x59, 0x39, 0x59, 0x0a, 0x59, 0xd6, 0x58, 0x96, 0x58, 0x55, 0x58, + 0x1e, 0x58, 0xf1, 0x57, 0xc8, 0x57, 0x7e, 0x57, 0x44, 0x57, 0x11, 0x57, + 0xd4, 0x56, 0x93, 0x56, 0x4c, 0x56, 0x11, 0x56, 0xd7, 0x55, 0xae, 0x55, + 0x72, 0x55, 0x3c, 0x55, 0x0c, 0x55, 0xd1, 0x54, 0x98, 0x54, 0x63, 0x54, + 0x2b, 0x54, 0xf8, 0x53, 0xc6, 0x53, 0x81, 0x53, 0x4b, 0x53, 0x19, 0x53, + 0xea, 0x52, 0xb2, 0x52, 0x7e, 0x52, 0x30, 0x52, 0xc5, 0x51, 0x46, 0x51, + 0xca, 0x50, 0x55, 0x50, 0xd7, 0x4f, 0x5d, 0x4f, 0xe4, 0x4e, 0x79, 0x4e, + 0xfb, 0x4d, 0x83, 0x4d, 0x02, 0x4d, 0x8a, 0x4c, 0x1f, 0x4c, 0x98, 0x4b, + 0x20, 0x4b, 0xa7, 0x4a, 0x36, 0x4a, 0xc0, 0x49, 0x44, 0x49, 0xc3, 0x48, + 0x44, 0x48, 0xd5, 0x47, 0x59, 0x47, 0xe6, 0x46, 0x63, 0x46, 0xf8, 0x45, + 0x79, 0x45, 0xfa, 0x44, 0x80, 0x44, 0x01, 0x44, 0x7a, 0x43, 0x04, 0x43, + 0x85, 0x42, 0x07, 0x42, 0x92, 0x41, 0x17, 0x41, 0x94, 0x40, 0x16, 0x40, + 0x9f, 0x3f, 0x20, 0x3f, 0x9c, 0x3e, 0x29, 0x3e, 0x9c, 0x3d, 0x20, 0x3d, + 0x88, 0x3c, 0x0c, 0x3c, 0x87, 0x3b, 0x07, 0x3b, 0x89, 0x3a, 0xfb, 0x39, + 0x6f, 0x39, 0xe7, 0x38, 0x55, 0x38, 0xcf, 0x37, 0x43, 0x37, 0xb5, 0x36, + 0x2a, 0x36, 0x9c, 0x35, 0x0a, 0x35, 0x83, 0x34, 0xe6, 0x33, 0x53, 0x33, + 0xba, 0x32, 0x1d, 0x32, 0x78, 0x31, 0xcb, 0x30, 0x34, 0x30, 0x8e, 0x2f, + 0xf6, 0x2e, 0x56, 0x2e, 0xab, 0x2d, 0xfe, 0x2c, 0x4c, 0x2c, 0x9f, 0x2b, + 0xed, 0x2a, 0x36, 0x2a, 0x7b, 0x29, 0xb9, 0x28, 0x02, 0x28, 0x41, 0x27, + 0x81, 0x26, 0xb9, 0x25, 0xfb, 0x24, 0x2d, 0x24, 0x66, 0x23, 0x98, 0x22, + 0xc6, 0x21, 0xe9, 0x20, 0x0d, 0x20, 0x28, 0x1f, 0x4c, 0x1e, 0x64, 0x1d, + 0x66, 0x1c, 0x8c, 0x1b, 0x96, 0x1a, 0xac, 0x19, 0xb2, 0x18, 0xbb, 0x17, + 0xc2, 0x16, 0xc7, 0x15, 0xcb, 0x14, 0xcd, 0x13, 0xc4, 0x12, 0xca, 0x11, + 0xb6, 0x10, 0xb8, 0x0f, 0xa3, 0x0e, 0x9e, 0x0d, 0x88, 0x0c, 0x86, 0x0b, + 0x7b, 0x0a, 0x7c, 0x09, 0x6d, 0x08, 0x5b, 0x07, 0x4a, 0x06, 0x38, 0x05, + 0x2f, 0x04, 0x1c, 0x03, 0x10, 0x02, 0xf6, 0x00, 0xe9, 0xff, 0xe5, 0xfe, + 0xcf, 0xfd, 0xc8, 0xfc, 0xb1, 0xfb, 0xa7, 0xfa, 0x8d, 0xf9, 0x7b, 0xf8, + 0x7e, 0xf7, 0x77, 0xf6, 0x68, 0xf5, 0x62, 0xf4, 0x49, 0xf3, 0x42, 0xf2, + 0x41, 0xf1, 0x3e, 0xf0, 0x49, 0xef, 0x47, 0xee, 0x56, 0xed, 0x46, 0xec, + 0x56, 0xeb, 0x5c, 0xea, 0x6c, 0xe9, 0x7d, 0xe8, 0x9c, 0xe7, 0x99, 0xe6, + 0xbf, 0xe5, 0xc9, 0xe4, 0xe5, 0xe3, 0xfd, 0xe2, 0x17, 0xe2, 0x26, 0xe1, + 0x44, 0xe0, 0x6d, 0xdf, 0x9f, 0xde, 0xc5, 0xdd, 0xec, 0xdc, 0x26, 0xdc, + 0x58, 0xdb, 0x91, 0xda, 0xb7, 0xd9, 0xf5, 0xd8, 0x27, 0xd8, 0x63, 0xd7, + 0x96, 0xd6, 0xd5, 0xd5, 0x1a, 0xd5, 0x52, 0xd4, 0x9d, 0xd3, 0xde, 0xd2, + 0x27, 0xd2, 0x6c, 0xd1, 0xb3, 0xd0, 0xf6, 0xcf, 0x51, 0xcf, 0x98, 0xce, + 0xe9, 0xcd, 0x2f, 0xcd, 0x88, 0xcc, 0xdc, 0xcb, 0x41, 0xcb, 0x9f, 0xca, + 0x01, 0xca, 0x60, 0xc9, 0xc4, 0xc8, 0x13, 0xc8, 0x7e, 0xc7, 0xe2, 0xc6, + 0x51, 0xc6, 0xb6, 0xc5, 0x1a, 0xc5, 0x8e, 0xc4, 0xf6, 0xc3, 0x74, 0xc3, + 0xdf, 0xc2, 0x59, 0xc2, 0xd2, 0xc1, 0x47, 0xc1, 0xbe, 0xc0, 0x3b, 0xc0, + 0xbe, 0xbf, 0x3e, 0xbf, 0xc4, 0xbe, 0x39, 0xbe, 0xbf, 0xbd, 0x3e, 0xbd, + 0xd7, 0xbc, 0x5d, 0xbc, 0xec, 0xbb, 0x73, 0xbb, 0x07, 0xbb, 0x96, 0xba, + 0x24, 0xba, 0xb5, 0xb9, 0x49, 0xb9, 0xdd, 0xb8, 0x76, 0xb8, 0x02, 0xb8, + 0xa8, 0xb7, 0x3c, 0xb7, 0xee, 0xb6, 0x82, 0xb6, 0x2b, 0xb6, 0xc3, 0xb5, + 0x6e, 0xb5, 0x14, 0xb5, 0xc4, 0xb4, 0x6b, 0xb4, 0x20, 0xb4, 0xd2, 0xb3, + 0x78, 0xb3, 0x2c, 0xb3, 0xe6, 0xb2, 0x9e, 0xb2, 0x58, 0xb2, 0x1a, 0xb2, + 0xea, 0xb1, 0xa6, 0xb1, 0x63, 0xb1, 0x2b, 0xb1, 0xf3, 0xb0, 0xb8, 0xb0, + 0x7b, 0xb0, 0x4e, 0xb0, 0x20, 0xb0, 0xf9, 0xaf, 0xc6, 0xaf, 0xa2, 0xaf, + 0x84, 0xaf, 0x5e, 0xaf, 0x44, 0xaf, 0x21, 0xaf, 0x06, 0xaf, 0xe9, 0xae, + 0xe2, 0xae, 0xd0, 0xae, 0xc3, 0xae, 0xba, 0xae, 0xc1, 0xae, 0xaf, 0xae, + 0xbc, 0xae, 0xb5, 0xae, 0xc0, 0xae, 0xc3, 0xae, 0xd7, 0xae, 0xdd, 0xae, + 0xfb, 0xae, 0x0a, 0xaf, 0x16, 0xaf, 0x37, 0xaf, 0x4a, 0xaf, 0x70, 0xaf, + 0x86, 0xaf, 0xa9, 0xaf, 0xc7, 0xaf, 0xec, 0xaf, 0x12, 0xb0, 0x42, 0xb0, + 0x66, 0xb0, 0x91, 0xb0, 0xc0, 0xb0, 0xee, 0xb0, 0x1a, 0xb1, 0x4c, 0xb1, + 0x77, 0xb1, 0xb3, 0xb1, 0xdd, 0xb1, 0x10, 0xb2, 0x47, 0xb2, 0x70, 0xb2, + 0xb8, 0xb2, 0xef, 0xb2, 0x26, 0xb3, 0x64, 0xb3, 0x90, 0xb3, 0xd8, 0xb3, + 0x07, 0xb4, 0x4b, 0xb4, 0x83, 0xb4, 0xc7, 0xb4, 0xf4, 0xb4, 0x35, 0xb5, + 0x70, 0xb5, 0xbc, 0xb5, 0xf0, 0xb5, 0x39, 0xb6, 0x7d, 0xb6, 0xb7, 0xb6, + 0xfa, 0xb6, 0x2e, 0xb7, 0x7d, 0xb7, 0xbb, 0xb7, 0x01, 0xb8, 0x39, 0xb8, + 0x80, 0xb8, 0xbd, 0xb8, 0x05, 0xb9, 0x46, 0xb9, 0x94, 0xb9, 0xcd, 0xb9, + 0x17, 0xba, 0x5b, 0xba, 0x9e, 0xba, 0xdf, 0xba, 0x27, 0xbb, 0x6a, 0xbb, + 0xbc, 0xbb, 0xf6, 0xbb, 0x3a, 0xbc, 0x83, 0xbc, 0xc3, 0xbc, 0x16, 0xbd, + 0x58, 0xbd, 0xa2, 0xbd, 0xe0, 0xbd, 0x24, 0xbe, 0x70, 0xbe, 0xa1, 0xbe, + 0xfa, 0xbe, 0x37, 0xbf, 0x8d, 0xbf, 0xc9, 0xbf, 0x1d, 0xc0, 0x5d, 0xc0, + 0xa6, 0xc0, 0xe6, 0xc0, 0x2f, 0xc1, 0x7a, 0xc1, 0xcb, 0xc1, 0x2f, 0xc2, + 0x95, 0xc2, 0xfa, 0xc2, 0x55, 0xc3, 0xbb, 0xc3, 0x1e, 0xc4, 0x86, 0xc4, + 0xec, 0xc4, 0x4b, 0xc5, 0xab, 0xc5, 0x04, 0xc6, 0x72, 0xc6, 0xc6, 0xc6, + 0x3a, 0xc7, 0x8e, 0xc7, 0xfd, 0xc7, 0x5a, 0xc8, 0xc0, 0xc8, 0x17, 0xc9, + 0x79, 0xc9, 0xd5, 0xc9, 0x43, 0xca, 0x98, 0xca, 0x05, 0xcb, 0x64, 0xcb, + 0xc3, 0xcb, 0x1e, 0xcc, 0x81, 0xcc, 0xe3, 0xcc, 0x40, 0xcd, 0xa6, 0xcd, + 0x0a, 0xce, 0x6a, 0xce, 0xc0, 0xce, 0x26, 0xcf, 0x81, 0xcf, 0xf0, 0xcf, + 0x48, 0xd0, 0xad, 0xd0, 0x07, 0xd1, 0x71, 0xd1, 0xca, 0xd1, 0x2b, 0xd2, + 0x8a, 0xd2, 0xed, 0xd2, 0x50, 0xd3, 0xa1, 0xd3, 0x0f, 0xd4, 0x6f, 0xd4, + 0xd6, 0xd4, 0x30, 0xd5, 0x93, 0xd5, 0xf6, 0xd5, 0x55, 0xd6, 0xb5, 0xd6, + 0x12, 0xd7, 0x7b, 0xd7, 0xde, 0xd7, 0x34, 0xd8, 0x93, 0xd8, 0xe9, 0xd8, + 0x61, 0xd9, 0xbb, 0xd9, 0x2b, 0xda, 0x88, 0xda, 0xeb, 0xda, 0x4f, 0xdb, + 0xb9, 0xdb, 0x21, 0xdc, 0x80, 0xdc, 0xf7, 0xdc, 0x53, 0xdd, 0xbb, 0xdd, + 0x2b, 0xde, 0xa4, 0xde, 0x05, 0xdf, 0x74, 0xdf, 0xd8, 0xdf, 0x44, 0xe0, + 0xb4, 0xe0, 0x26, 0xe1, 0x91, 0xe1, 0x01, 0xe2, 0x77, 0xe2, 0xeb, 0xe2, + 0x5e, 0xe3, 0xc7, 0xe3, 0x44, 0xe4, 0xb2, 0xe4, 0x25, 0xe5, 0xa3, 0xe5, + 0x15, 0xe6, 0x97, 0xe6, 0x0b, 0xe7, 0x8b, 0xe7, 0x10, 0xe8, 0x7d, 0xe8, + 0x06, 0xe9, 0x74, 0xe9, 0xff, 0xe9, 0x82, 0xea, 0x01, 0xeb, 0x85, 0xeb, + 0xfa, 0xeb, 0x91, 0xec, 0x07, 0xed, 0x8f, 0xed, 0x15, 0xee, 0x9a, 0xee, + 0x26, 0xef, 0xa5, 0xef, 0x26, 0xf0, 0xb2, 0xf0, 0x3e, 0xf1, 0xca, 0xf1, + 0x45, 0xf2, 0xcc, 0xf2, 0x51, 0xf3, 0xdc, 0xf3, 0x5c, 0xf4, 0xe8, 0xf4, + 0x6e, 0xf5, 0xf9, 0xf5, 0x79, 0xf6, 0xf9, 0xf6, 0x7d, 0xf7, 0x08, 0xf8, + 0x91, 0xf8, 0x18, 0xf9, 0x95, 0xf9, 0x18, 0xfa, 0xa5, 0xfa, 0x21, 0xfb, + 0xa9, 0xfb, 0x2a, 0xfc, 0xa7, 0xfc, 0x23, 0xfd, 0xa3, 0xfd, 0x2b, 0xfe, + 0x9c, 0xfe, 0x2b, 0xff, 0xa0, 0xff, 0x1c, 0x00, 0x9a, 0x00, 0x11, 0x01, + 0x9a, 0x01, 0x14, 0x02, 0x8c, 0x02, 0x07, 0x03, 0x84, 0x03, 0xf7, 0x03, + 0x75, 0x04, 0xf3, 0x04, 0x65, 0x05, 0xe8, 0x05, 0x54, 0x06, 0xd3, 0x06, + 0x48, 0x07, 0xc2, 0x07, 0x38, 0x08, 0xad, 0x08, 0x28, 0x09, 0x99, 0x09, + 0x11, 0x0a, 0x79, 0x0a, 0xf5, 0x0a, 0x5c, 0x0b, 0xd1, 0x0b, 0x3f, 0x0c, + 0xb5, 0x0c, 0x2c, 0x0d, 0x9a, 0x0d, 0x0b, 0x0e, 0x74, 0x0e, 0xe6, 0x0e, + 0x45, 0x0f, 0xbd, 0x0f, 0x2f, 0x10, 0x9a, 0x10, 0x05, 0x11, 0x6c, 0x11, + 0xdb, 0x11, 0x40, 0x12, 0xaa, 0x12, 0x14, 0x13, 0x81, 0x13, 0xe9, 0x13, + 0x4d, 0x14, 0xb9, 0x14, 0x18, 0x15, 0x88, 0x15, 0xe6, 0x15, 0x58, 0x16, + 0xb9, 0x16, 0x1c, 0x17, 0x7e, 0x17, 0xe3, 0x17, 0x43, 0x18, 0xac, 0x18, + 0x08, 0x19, 0x6d, 0x19, 0xce, 0x19, 0x34, 0x1a, 0x90, 0x1a, 0xf5, 0x1a, + 0x53, 0x1b, 0xbb, 0x1b, 0x07, 0x1c, 0x6f, 0x1c, 0xc2, 0x1c, 0x28, 0x1d, + 0x84, 0x1d, 0xe8, 0x1d, 0x35, 0x1e, 0xa2, 0x1e, 0xf8, 0x1e, 0x59, 0x1f, + 0xb8, 0x1f, 0x0c, 0x20, 0x69, 0x20, 0xbe, 0x20, 0x19, 0x21, 0x66, 0x21, + 0xc6, 0x21, 0x1f, 0x22, 0x70, 0x22, 0xbe, 0x22, 0x18, 0x23, 0x72, 0x23, + 0xbf, 0x23, 0x0f, 0x24, 0x67, 0x24, 0xc0, 0x24, 0x08, 0x25, 0x51, 0x25, + 0xa6, 0x25, 0xf4, 0x25, 0x42, 0x26, 0x93, 0x26, 0xd6, 0x26, 0x25, 0x27, + 0x6c, 0x27, 0xb7, 0x27, 0x07, 0x28, 0x49, 0x28, 0x96, 0x28, 0xda, 0x28, + 0x22, 0x29, 0x66, 0x29, 0xa4, 0x29, 0xe8, 0x29, 0x20, 0x2a, 0x62, 0x2a, + 0xa9, 0x2a, 0xe5, 0x2a, 0x21, 0x2b, 0x5a, 0x2b, 0x97, 0x2b, 0xc1, 0x2b, + 0xfe, 0x2b, 0x28, 0x2c, 0x57, 0x2c, 0x88, 0x2c, 0xae, 0x2c, 0xd3, 0x2c, + 0xfa, 0x2c, 0x17, 0x2d, 0x33, 0x2d, 0x4b, 0x2d, 0x5d, 0x2d, 0x68, 0x2d, + 0x81, 0x2d, 0x92, 0x2d, 0x9e, 0x2d, 0xa9, 0x2d, 0xbb, 0x2d, 0xc3, 0x2d, + 0xcd, 0x2d, 0xd5, 0x2d, 0xcd, 0x2d, 0xdc, 0x2d, 0xe3, 0x2d, 0xe1, 0x2d, + 0xdd, 0x2d, 0xd9, 0x2d, 0xd7, 0x2d, 0xcf, 0x2d, 0xe0, 0x2d, 0xd2, 0x2d, + 0xd2, 0x2d, 0xcb, 0x2d, 0xb7, 0x2d, 0xb6, 0x2d, 0xa1, 0x2d, 0x9e, 0x2d, + 0x8b, 0x2d, 0x84, 0x2d, 0x68, 0x2d, 0x6a, 0x2d, 0x4e, 0x2d, 0x45, 0x2d, + 0x2f, 0x2d, 0x18, 0x2d, 0x15, 0x2d, 0xef, 0x2c, 0xe8, 0x2c, 0xc9, 0x2c, + 0xc7, 0x2c, 0xaa, 0x2c, 0x9b, 0x2c, 0x7c, 0x2c, 0x64, 0x2c, 0x3c, 0x2c, + 0x2e, 0x2c, 0x16, 0x2c, 0x05, 0x2c, 0xe1, 0x2b, 0xc8, 0x2b, 0xb5, 0x2b, + 0x9a, 0x2b, 0x7c, 0x2b, 0x61, 0x2b, 0x3f, 0x2b, 0x21, 0x2b, 0x01, 0x2b, + 0xee, 0x2a, 0xd0, 0x2a, 0xb3, 0x2a, 0x95, 0x2a, 0x6d, 0x2a, 0x50, 0x2a, + 0x2b, 0x2a, 0x0b, 0x2a, 0xe9, 0x29, 0xd1, 0x29, 0xa8, 0x29, 0x97, 0x29, + 0x6c, 0x29, 0x51, 0x29, 0x24, 0x29, 0x03, 0x29, 0xe6, 0x28, 0xbe, 0x28, + 0xa1, 0x28, 0x80, 0x28, 0x64, 0x28, 0x38, 0x28, 0x12, 0x28, 0xf0, 0x27, + 0xd3, 0x27, 0xac, 0x27, 0x94, 0x27, 0x67, 0x27, 0x4a, 0x27, 0x1c, 0x27, + 0xf7, 0x26, 0xd1, 0x26, 0xb6, 0x26, 0x8d, 0x26, 0x6e, 0x26, 0x4b, 0x26, + 0x25, 0x26, 0x02, 0x26, 0xd8, 0x25, 0xbe, 0x25, 0x93, 0x25, 0x7c, 0x25, + 0x4a, 0x25, 0x27, 0x25, 0x07, 0x25, 0xdc, 0x24, 0xbb, 0x24, 0x9a, 0x24, + 0x78, 0x24, 0x4c, 0x24, 0x26, 0x24, 0x00, 0x24, 0xd7, 0x23, 0xc0, 0x23, + 0x94, 0x23, 0x71, 0x23, 0x45, 0x23, 0x1c, 0x23, 0x00, 0x23, 0xd4, 0x22, + 0xb5, 0x22, 0x8e, 0x22, 0x67, 0x22, 0x39, 0x22, 0x00, 0x22, 0xbd, 0x21, + 0x87, 0x21, 0x46, 0x21, 0x01, 0x21, 0xca, 0x20, 0x89, 0x20, 0x4a, 0x20, + 0x17, 0x20, 0xd6, 0x1f, 0x9a, 0x1f, 0x5e, 0x1f, 0x20, 0x1f, 0xe0, 0x1e, + 0xa3, 0x1e, 0x5f, 0x1e, 0x29, 0x1e, 0xf0, 0x1d, 0xb8, 0x1d, 0x78, 0x1d, + 0x36, 0x1d, 0x04, 0x1d, 0xc6, 0x1c, 0x8b, 0x1c, 0x4d, 0x1c, 0x18, 0x1c, + 0xd9, 0x1b, 0x97, 0x1b, 0x5c, 0x1b, 0x2b, 0x1b, 0xf4, 0x1a, 0xb1, 0x1a, + 0x7c, 0x1a, 0x32, 0x1a, 0x02, 0x1a, 0xc6, 0x19, 0x8b, 0x19, 0x59, 0x19, + 0x10, 0x19, 0xd7, 0x18, 0x9c, 0x18, 0x62, 0x18, 0x22, 0x18, 0xe8, 0x17, + 0xb1, 0x17, 0x7c, 0x17, 0x34, 0x17, 0xf9, 0x16, 0xc0, 0x16, 0x8b, 0x16, + 0x55, 0x16, 0x14, 0x16, 0xdd, 0x15, 0x9f, 0x15, 0x65, 0x15, 0x2b, 0x15, + 0xea, 0x14, 0xb9, 0x14, 0x70, 0x14, 0x3d, 0x14, 0x05, 0x14, 0xc1, 0x13, + 0x86, 0x13, 0x45, 0x13, 0x09, 0x13, 0xca, 0x12, 0x90, 0x12, 0x57, 0x12, + 0x1a, 0x12, 0xe1, 0x11, 0x9b, 0x11, 0x61, 0x11, 0x1d, 0x11, 0xe1, 0x10, + 0x9d, 0x10, 0x64, 0x10, 0x17, 0x10, 0xde, 0x0f, 0xa1, 0x0f, 0x60, 0x0f, + 0x1b, 0x0f, 0xd8, 0x0e, 0x90, 0x0e, 0x5b, 0x0e, 0x0e, 0x0e, 0xd3, 0x0d, + 0x86, 0x0d, 0x4d, 0x0d, 0xf5, 0x0c, 0xba, 0x0c, 0x68, 0x0c, 0x2a, 0x0c, + 0xde, 0x0b, 0x94, 0x0b, 0x4e, 0x0b, 0x07, 0x0b, 0xbb, 0x0a, 0x6c, 0x0a, + 0x25, 0x0a, 0xd4, 0x09, 0x89, 0x09, 0x39, 0x09, 0xe6, 0x08, 0xa3, 0x08, + 0x4f, 0x08, 0x02, 0x08, 0xa7, 0x07, 0x5f, 0x07, 0x08, 0x07, 0xba, 0x06, + 0x68, 0x06, 0x1f, 0x06, 0xc5, 0x05, 0x7a, 0x05, 0x1f, 0x05, 0xd7, 0x04, + 0x85, 0x04, 0x31, 0x04, 0xde, 0x03, 0x89, 0x03, 0x3a, 0x03, 0xe9, 0x02, + 0x96, 0x02, 0x47, 0x02, 0xf7, 0x01, 0xa4, 0x01, 0x5d, 0x01, 0x06, 0x01, + 0xb9, 0x00 +}; +unsigned int kick_raw_len = 6350; diff --git a/third-party/TeensyVariablePlayback/extras/linux/sd_raw/CMakeLists.txt b/third-party/TeensyVariablePlayback/extras/linux/sd_raw/CMakeLists.txt new file mode 100644 index 0000000..f8ac13d --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/linux/sd_raw/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.10) +project(sd_raw) +set(CMAKE_CXX_STANDARD 14) + +find_package(teensy_x86_stubs) +include_directories(${teensy_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs) +include_directories(${teensy_audio_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_x86_sd_stubs) +include_directories(${teensy_x86_sd_stubs_INCLUDE_DIR}) + +include_directories(../../../src) +add_executable(sd_raw sd_raw.cpp) + +target_link_libraries(sd_raw ${teensy_x86_stubs_LIBS}) +target_link_libraries(sd_raw ${teensy_audio_x86_stubs_LIBS}) +target_link_libraries(sd_raw ${teensy_x86_sd_stubs_LIBS}) +target_link_libraries(sd_raw teensy_variable_playback) diff --git a/third-party/TeensyVariablePlayback/extras/linux/sd_raw/sd_raw.cpp b/third-party/TeensyVariablePlayback/extras/linux/sd_raw/sd_raw.cpp new file mode 100644 index 0000000..2ae2411 --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/linux/sd_raw/sd_raw.cpp @@ -0,0 +1,74 @@ +// Plays a RAW (16-bit signed) PCM audio file at slower or faster rate +// this example requires an uSD-card inserted to teensy 3.6 with a file called DEMO.RAW +#include +#include +#include +#include "SD.h" +#include "playsdresmp.h" + +// GUItool: begin automatically generated code +AudioControlSGTL5000 audioShield; +AudioPlaySdResmp playSdRaw1; //xy=324,457 +AudioOutputI2S i2s2; //xy=840.8571472167969,445.5714416503906 +AudioConnection patchCord1(playSdRaw1, 0, i2s2, 0); +AudioConnection patchCord2(playSdRaw1, 0, i2s2, 1); +// GUItool: end automatically generated code + +#define A14 10 +#define BUILTIN_SDCARD 10 + +const char* _filename = "DEMO.RAW"; +const int analogInPin = A14; + +int sensorValue = 0; + +void setup() { + analogReference(0); + pinMode(analogInPin, INPUT); + + Serial.begin(57600); + + if (!(SD.begin(BUILTIN_SDCARD))) { + // stop here if no SD card, but print a message + while (1) { + Serial.println("Unable to access the SD card"); + delay(500); + } + } + + AudioMemory(24); + + audioShield.enable(); + audioShield.volume(0.5); + + playSdRaw1.playRaw(_filename, 1); + playSdRaw1.setPlaybackRate(-1); + Serial.println("playing..."); +} + +void loop() { + + int newsensorValue = analogRead(analogInPin); + if (newsensorValue / 64 != sensorValue / 64) { + sensorValue = newsensorValue; + float rate = (sensorValue - 512.0) / 512.0; + playSdRaw1.setPlaybackRate(rate); + Serial.printf("rate: %f %x\n", rate, sensorValue); + } + + if (!playSdRaw1.isPlaying()) { + Serial.println("playing..."); + playSdRaw1.playRaw(_filename, 1); + } +} + +#ifdef BUILD_FOR_LINUX +int main() { + initialize_mock_arduino(); + SD.setSDCardFileData("234234234", 5); + setup(); + while(true){ + loop(); + } +} +#endif \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/extras/soundio/save_raw/CMakeLists.txt b/third-party/TeensyVariablePlayback/extras/soundio/save_raw/CMakeLists.txt new file mode 100644 index 0000000..529b888 --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/soundio/save_raw/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.10) +set(CMAKE_CXX_STANDARD 11) +project(save_raw) + +find_package(teensy_x86_stubs) +include_directories(${teensy_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_x86_sd_stubs) +include_directories(${teensy_x86_sd_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs) +include_directories(${teensy_audio_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs_soundio) +if(teensy_audio_x86_stubs_soundio_FOUND) + include_directories(${teensy_audio_x86_stubs_soundio_INCLUDE_DIR}) + + include_directories(/usr/local/include) #soundio + include_directories(../../../src) + + add_executable(save_raw save_raw.cpp) + target_link_libraries(save_raw teensy_variable_playback) + + if(WIN32) + elseif(UNIX AND NOT APPLE) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") + SET(SOUNDIO_LIBS -L/usr/lib/x86_64-linux-gnu -lsoundio) + elseif(APPLE) + INCLUDE_DIRECTORIES(/System/Library/Frameworks) + FIND_LIBRARY(glfw3_LIBRARY glfw) + FIND_LIBRARY(COCOA_LIBRARY Cocoa) + FIND_LIBRARY(OpenGL_LIBRARY OpenGL) + FIND_LIBRARY(IOKit_LIBRARY IOKit) + FIND_LIBRARY(glew_LIBRARY glew) + FIND_LIBRARY(CoreVideo_LIBRARY CoreVideo) + MARK_AS_ADVANCED(COCOA_LIBRARY OpenGL_LIBRARY) + FIND_LIBRARY(FREETYPE_LIBRARIES FreeType) + SET(APPLE_LIBS ${COCOA_LIBRARY} ${IOKit_LIBRARY} ${OpenGL_LIBRARY} ${CoreVideo_LIBRARY}) + SET(APPLE_LIBS ${APPLE_LIBS} ${GLFW3_LIBRARY} ${ASSIMP_LIBRARY} ${FREETYPE_LIBRARIES} ${glfw3_LIBRARY} ${glew_LIBRARY}) + set(LIBS ${LIBS} ${APPLE_LIBS}) + target_link_libraries(save_raw + "-framework CoreServices" + "-framework CoreAudio" + "-framework Foundation" + "-framework AudioUnit") + SET(SOUNDIO_LIBS /usr/local/lib/libsoundio.a) + endif() + + target_link_libraries(save_raw ${LIBS} ${teensy_x86_stubs_LIBS} ${teensy_x86_sd_stubs_LIBS} ${teensy_audio_x86_stubs_LIBS} ${teensy_audio_x86_stubs_soundio_LIBS} ${teensy_st7735_linux_stubs_LIBS} ${teensy_st7735_linux_extras_opengl_LIBS} ${SOUNDIO_LIBS}) +#set(CMAKE_VERBOSE_MAKEFILE 1) +endif() \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/extras/soundio/save_raw/save_raw.cpp b/third-party/TeensyVariablePlayback/extras/soundio/save_raw/save_raw.cpp new file mode 100644 index 0000000..1cfbdd6 --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/soundio/save_raw/save_raw.cpp @@ -0,0 +1,692 @@ +// Plays a RAW (16-bit signed) PCM audio file at slower or faster rate +// this example plays a sample stored in an array +#include +#include +#include "../../../src/playarrayresmp.h" +#include "output_soundio.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// GUItool: begin automatically generated code +AudioPlayArrayResmp rraw_a1; //xy=306,225 +AudioRecordQueue queue1; //xy=609,267 +AudioOutputSoundIO sio_out1; //xy=612,224 +AudioConnection patchCord1(rraw_a1, 0, sio_out1, 0); +AudioConnection patchCord2(rraw_a1, 0, sio_out1, 1); +AudioConnection patchCord3(rraw_a1, 0, queue1, 0); +// GUItool: end automatically generated code + +extern unsigned int kick_raw_len; +extern unsigned char kick_raw[]; + +int16_t buffer[512] = {0}; +File frec; + +unsigned long lastSamplePlayed = 0; +void my_handler(sig_atomic_t i); +static char stack_body[64*1024]; +static stack_t sigseg_stack; +static struct sigaction sigseg_handler; + +void crash_handler(sig_atomic_t i); + +void setup() { + Serial.begin(9600); + + rraw_a1.setPlaybackRate(0.25f); + rraw_a1.enableInterpolation(true); + //rraw_a1.play((int16_t*)kick_raw, kick_raw_len/2); + Serial.println("setup done"); + + if (SD.exists("RECORD.RAW")) { + // The SD library writes new data to the end of the + // file, so to start a new recording, the old file + // must be deleted before new data is written. + SD.remove("RECORD.RAW"); + } + frec = SD.open("RECORD.RAW", O_WRITE); + + AudioMemory(120); + + if (frec) { + queue1.begin(); + Serial.println("startRecording"); + } else { + Serial.println("recording failed..."); + } +} + +void loop() { + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 1000) { + if (!rraw_a1.isPlaying()) { + rraw_a1.playRaw((int16_t *)kick_raw, kick_raw_len/2, 1); + lastSamplePlayed = currentMillis; + + Serial.print("Memory: "); + Serial.print(AudioMemoryUsage()); + Serial.print(","); + Serial.print(AudioMemoryUsageMax()); + Serial.println(); + } + } + + if (queue1.available() >= 1) { + int16_t* incomming = queue1.readBuffer(); + //Serial.printf("sizeof(incomming)=%i\n", sizeof(incomming)); + //if (incomming != NULL && sizeof(incomming) >= 256) { + if (incomming != NULL) { + memcpy(buffer, incomming, 256); + queue1.freeBuffer(); + frec.write((unsigned char *)buffer, 256); + frec.flush(); + } + //else { + // arduino_should_exit = true; + //Serial.printf("sizeof(incomming)=%i\n", sizeof(incomming)); + //} + } + delay(1); +} + +int main() { + signal (SIGINT,my_handler); + signal (SIGSEGV,crash_handler); + + sigseg_stack.ss_sp = stack_body; + sigseg_stack.ss_flags = SS_ONSTACK; + sigseg_stack.ss_size = sizeof(stack_body); + // assert(!sigaltstack(&sigseg_stack, nullptr)); + sigseg_handler.sa_flags = SA_ONSTACK; + sigseg_handler.sa_handler = &crash_handler; + // assert(!sigaction(SIGSEGV, &sigseg_handler, nullptr)); + + initialize_mock_arduino(); + SD.setSDCardFolderPath("."); + setup(); + while(!arduino_should_exit){ + loop(); + } + delay(1000); + frec.close(); +} + +void my_handler(sig_atomic_t i){ + if ( i== SIGINT) { + arduino_should_exit = true; + printf("Caught signal %d\n",i); + } else + { + cerr << "sig seg fault handler" << endl; + const int asize = 10; + void *array[asize]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, asize); + + // print out all the frames to stderr + cerr << "stack trace: " << endl; + backtrace_symbols_fd(array, size, STDERR_FILENO); + cerr << "resend SIGSEGV to get core dump" << endl; + signal(i, SIG_DFL); + kill(getpid(), i); + } +} +void crash_handler(sig_atomic_t i){ + cerr << "sig seg fault handler" << endl; + const int asize = 10; + void *array[asize]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, asize); + + // print out all the frames to stderr + cerr << "stack trace: " << endl; + backtrace_symbols_fd(array, size, STDERR_FILENO); + cerr << "resend SIGSEGV to get core dump" << endl; + signal(i, SIG_DFL); + kill(getpid(), i); +} + +unsigned char kick_raw[] = { + 0x99, 0x02, 0xd7, 0x02, 0xfa, 0x02, 0x5f, 0x03, 0xc1, 0x03, 0x2a, 0x04, + 0xad, 0x04, 0xa5, 0x05, 0x76, 0x06, 0x2f, 0x07, 0x9e, 0x07, 0xe2, 0x07, + 0x43, 0x08, 0x92, 0x08, 0xb2, 0x08, 0xe8, 0x08, 0x16, 0x09, 0xda, 0x08, + 0x51, 0x08, 0x01, 0x08, 0x25, 0x08, 0x70, 0x08, 0xc3, 0x08, 0x23, 0x09, + 0x95, 0x09, 0x19, 0x0a, 0x83, 0x0a, 0x7e, 0x0a, 0xd0, 0x0a, 0x65, 0x0b, + 0xf6, 0x0b, 0x89, 0x0c, 0xd1, 0x0c, 0xcf, 0x0c, 0x1a, 0x0d, 0xe5, 0x0d, + 0x5e, 0x0e, 0xbb, 0x0e, 0xec, 0x0e, 0xd9, 0x0e, 0x07, 0x0f, 0xc8, 0x0f, + 0x2a, 0x10, 0x04, 0x10, 0x28, 0x10, 0x54, 0x11, 0x8e, 0x13, 0x4b, 0x16, + 0x09, 0x19, 0x91, 0x1b, 0xf7, 0x1d, 0x55, 0x20, 0xd1, 0x22, 0xcb, 0x25, + 0x4d, 0x29, 0xa8, 0x2c, 0x7f, 0x2f, 0xda, 0x31, 0xac, 0x34, 0x0a, 0x3a, + 0x24, 0x47, 0x9d, 0x5b, 0xe9, 0x67, 0x29, 0x67, 0x24, 0x66, 0x26, 0x66, + 0xd2, 0x65, 0x9c, 0x65, 0x38, 0x65, 0x05, 0x65, 0x9f, 0x64, 0x64, 0x64, + 0x12, 0x64, 0xce, 0x63, 0x7c, 0x63, 0x32, 0x63, 0xe6, 0x62, 0x97, 0x62, + 0x49, 0x62, 0x01, 0x62, 0xb3, 0x61, 0x63, 0x61, 0x15, 0x61, 0xc4, 0x60, + 0x75, 0x60, 0x20, 0x60, 0xce, 0x5f, 0x7a, 0x5f, 0x28, 0x5f, 0xd5, 0x5e, + 0x81, 0x5e, 0x2d, 0x5e, 0xd3, 0x5d, 0x80, 0x5d, 0x2e, 0x5d, 0xe6, 0x5c, + 0x1a, 0x5c, 0x16, 0x5a, 0x01, 0x58, 0xb9, 0x56, 0x6d, 0x55, 0xf4, 0x53, + 0x49, 0x52, 0x83, 0x50, 0x87, 0x4e, 0x5f, 0x4c, 0x68, 0x4a, 0x5c, 0x48, + 0x62, 0x46, 0x5a, 0x44, 0xe2, 0x41, 0x08, 0x3f, 0x1c, 0x3c, 0x44, 0x39, + 0x35, 0x36, 0xcb, 0x32, 0xaf, 0x2f, 0xc8, 0x2c, 0xf8, 0x29, 0x55, 0x27, + 0x6a, 0x24, 0x0f, 0x21, 0x5e, 0x1d, 0xc3, 0x19, 0x7b, 0x16, 0x71, 0x13, + 0x6c, 0x10, 0x00, 0x0d, 0xd2, 0x08, 0x7f, 0x04, 0x7a, 0x01, 0x43, 0xff, + 0xb9, 0xfc, 0xfa, 0xf9, 0x3b, 0xf7, 0xcb, 0xf4, 0x2b, 0xf2, 0x02, 0xef, + 0x0c, 0xec, 0x3d, 0xe9, 0x21, 0xe6, 0xa6, 0xe2, 0x8a, 0xdf, 0x00, 0xdd, + 0xbc, 0xda, 0x9e, 0xd8, 0xc1, 0xd6, 0xd6, 0xd4, 0xd6, 0xd2, 0xad, 0xd0, + 0x5f, 0xce, 0xf0, 0xcb, 0xe9, 0xc9, 0x61, 0xc8, 0x75, 0xc7, 0x97, 0xc6, + 0x3e, 0xc5, 0x07, 0xc4, 0x8e, 0xc3, 0x18, 0xc3, 0x3a, 0xc2, 0x15, 0xc1, + 0x0e, 0xc0, 0xb3, 0xbf, 0xcf, 0xbf, 0xf8, 0xbf, 0xcc, 0xbf, 0x72, 0xbf, + 0x41, 0xbf, 0x2b, 0xbf, 0xe2, 0xbe, 0x99, 0xbe, 0x4e, 0xbe, 0x0e, 0xbe, + 0xcd, 0xbd, 0x7c, 0xbd, 0x8a, 0xbd, 0x88, 0xbd, 0x04, 0xbd, 0x0c, 0xbc, + 0xb3, 0xbb, 0xf6, 0xbb, 0xf1, 0xbb, 0x12, 0xbc, 0x6f, 0xbc, 0xcb, 0xbc, + 0xe4, 0xbc, 0x33, 0xbd, 0x1b, 0xbe, 0xac, 0xbe, 0x1e, 0xbf, 0x91, 0xbf, + 0x50, 0xc0, 0x40, 0xc1, 0x3d, 0xc2, 0x32, 0xc3, 0xdf, 0xc3, 0xad, 0xc4, + 0x77, 0xc5, 0xbe, 0xc6, 0xc7, 0xc8, 0x1d, 0xcb, 0x0e, 0xcd, 0x83, 0xce, + 0xf1, 0xcf, 0xb4, 0xd1, 0x7d, 0xd3, 0x86, 0xd5, 0x89, 0xd7, 0xd2, 0xd9, + 0x34, 0xdc, 0x28, 0xde, 0x23, 0xe0, 0x33, 0xe2, 0x0a, 0xe4, 0x59, 0xe5, + 0xfc, 0xe6, 0x98, 0xe9, 0x30, 0xec, 0x91, 0xee, 0xc2, 0xf0, 0x0d, 0xf3, + 0x35, 0xf5, 0xf3, 0xf6, 0xc4, 0xf8, 0xcb, 0xfa, 0xef, 0xfc, 0x65, 0xff, + 0x05, 0x02, 0x7c, 0x04, 0xde, 0x06, 0x75, 0x09, 0x2b, 0x0c, 0x9b, 0x0e, + 0xf3, 0x10, 0xb3, 0x13, 0x3a, 0x16, 0xeb, 0x18, 0x55, 0x1c, 0xad, 0x1f, + 0xa8, 0x22, 0x54, 0x25, 0xae, 0x27, 0x33, 0x2a, 0x16, 0x2d, 0x36, 0x30, + 0x84, 0x33, 0x94, 0x36, 0xbd, 0x38, 0xa2, 0x3a, 0x7d, 0x3c, 0x06, 0x3e, + 0x24, 0x3f, 0x27, 0x40, 0x7c, 0x41, 0xef, 0x42, 0x14, 0x44, 0xeb, 0x44, + 0x06, 0x46, 0x53, 0x47, 0x47, 0x48, 0x9b, 0x48, 0xaf, 0x48, 0xd7, 0x48, + 0x4c, 0x49, 0xa0, 0x49, 0xbe, 0x49, 0xd4, 0x49, 0xfa, 0x49, 0x5e, 0x4a, + 0xcc, 0x4a, 0x14, 0x4b, 0xfe, 0x4a, 0x22, 0x4b, 0x10, 0x4c, 0x0c, 0x4d, + 0xb2, 0x4d, 0x4c, 0x4e, 0x3e, 0x4e, 0x77, 0x4d, 0x98, 0x4c, 0xf6, 0x4b, + 0x67, 0x4b, 0xf0, 0x4a, 0x2a, 0x4a, 0xea, 0x48, 0x06, 0x48, 0x47, 0x47, + 0xb2, 0x46, 0xda, 0x45, 0xad, 0x44, 0x5c, 0x43, 0x43, 0x42, 0x9e, 0x41, + 0x0a, 0x41, 0x49, 0x40, 0xa6, 0x3f, 0x9d, 0x3e, 0x3c, 0x3d, 0xc6, 0x3b, + 0xf6, 0x39, 0x87, 0x37, 0xf6, 0x34, 0x87, 0x32, 0x2b, 0x30, 0x6f, 0x2d, + 0xfa, 0x2a, 0x3d, 0x29, 0x48, 0x27, 0xc2, 0x24, 0x49, 0x22, 0xca, 0x1f, + 0xa0, 0x1c, 0x7c, 0x19, 0x06, 0x17, 0xbf, 0x14, 0x9f, 0x12, 0x96, 0x10, + 0xf9, 0x0d, 0x3e, 0x0b, 0xe8, 0x08, 0x5c, 0x06, 0xe7, 0x02, 0x6e, 0xff, + 0xca, 0xfc, 0x5b, 0xfa, 0xa0, 0xf7, 0xe9, 0xf4, 0x9c, 0xf2, 0x66, 0xf0, + 0xaf, 0xed, 0xfd, 0xea, 0xcc, 0xe8, 0x6e, 0xe6, 0x82, 0xe3, 0x97, 0xe0, + 0xed, 0xdd, 0x62, 0xdb, 0x7b, 0xd8, 0xd3, 0xd5, 0x5f, 0xd3, 0x1a, 0xd1, + 0x44, 0xcf, 0xeb, 0xcd, 0x89, 0xcc, 0xca, 0xca, 0x4d, 0xc9, 0x35, 0xc8, + 0x53, 0xc7, 0x0c, 0xc6, 0x06, 0xc4, 0xca, 0xc1, 0x09, 0xc0, 0x9c, 0xbe, + 0xa8, 0xbd, 0xfd, 0xbc, 0xf2, 0xbb, 0x9b, 0xba, 0x20, 0xb9, 0xe4, 0xb7, + 0xc1, 0xb6, 0xcd, 0xb5, 0x12, 0xb5, 0x55, 0xb4, 0xd1, 0xb3, 0x86, 0xb3, + 0x19, 0xb3, 0xe8, 0xb2, 0xd7, 0xb2, 0x72, 0xb2, 0x27, 0xb2, 0xb7, 0xb1, + 0x67, 0xb1, 0x65, 0xb1, 0xae, 0xb1, 0x6b, 0xb1, 0xf2, 0xb0, 0xeb, 0xb0, + 0x0f, 0xb1, 0xfe, 0xb0, 0xeb, 0xb0, 0xcf, 0xb0, 0x94, 0xb0, 0x3e, 0xb0, + 0x29, 0xb0, 0x56, 0xb0, 0x0c, 0xb0, 0xb7, 0xaf, 0xfb, 0xaf, 0x37, 0xb0, + 0x96, 0xb0, 0x42, 0xb1, 0xe8, 0xb1, 0xb5, 0xb2, 0xc5, 0xb3, 0x93, 0xb4, + 0x93, 0xb4, 0xee, 0xb4, 0x59, 0xb6, 0xca, 0xb7, 0x87, 0xb8, 0x6f, 0xb8, + 0x33, 0xb8, 0xaf, 0xb8, 0x4a, 0xb9, 0x9d, 0xb9, 0xf2, 0xb9, 0x48, 0xba, + 0xd0, 0xba, 0xe5, 0xbb, 0x4e, 0xbd, 0xaf, 0xbe, 0xe9, 0xbf, 0xba, 0xc1, + 0xc2, 0xc3, 0x73, 0xc5, 0xa6, 0xc6, 0x6a, 0xc7, 0x83, 0xc8, 0x42, 0xca, + 0xc8, 0xcb, 0x34, 0xcd, 0x94, 0xce, 0xcc, 0xcf, 0x31, 0xd1, 0x27, 0xd3, + 0x8c, 0xd5, 0x61, 0xd7, 0x78, 0xd9, 0x3b, 0xdc, 0x40, 0xdf, 0xdd, 0xe1, + 0x0c, 0xe4, 0xe4, 0xe5, 0xd0, 0xe7, 0x65, 0xea, 0xc9, 0xec, 0xd7, 0xee, + 0xfc, 0xf0, 0x7c, 0xf3, 0xf6, 0xf5, 0x09, 0xf8, 0xde, 0xf9, 0xca, 0xfb, + 0xac, 0xfd, 0xc3, 0xff, 0x33, 0x02, 0xb1, 0x04, 0x24, 0x07, 0x57, 0x09, + 0x5f, 0x0b, 0xe6, 0x0d, 0xd1, 0x10, 0x6d, 0x13, 0x8f, 0x15, 0xfb, 0x17, + 0x43, 0x1a, 0x8e, 0x1c, 0x1a, 0x1f, 0x69, 0x21, 0x80, 0x23, 0x74, 0x25, + 0x62, 0x27, 0x07, 0x29, 0xa1, 0x2a, 0xa5, 0x2c, 0xdf, 0x2e, 0x57, 0x31, + 0xff, 0x33, 0xd1, 0x36, 0x6e, 0x39, 0x8a, 0x3b, 0x58, 0x3d, 0x32, 0x3f, + 0xc8, 0x40, 0x1b, 0x42, 0x22, 0x43, 0x1a, 0x44, 0x25, 0x45, 0xe5, 0x45, + 0x43, 0x46, 0x9b, 0x46, 0x6a, 0x47, 0x6f, 0x48, 0x69, 0x49, 0x6f, 0x4a, + 0xc7, 0x4b, 0x0e, 0x4d, 0x03, 0x4e, 0x78, 0x4e, 0xdf, 0x4e, 0x0b, 0x4f, + 0xea, 0x4e, 0xcb, 0x4e, 0x1b, 0x4f, 0x6e, 0x4f, 0xc3, 0x4f, 0xdc, 0x4f, + 0xcb, 0x4f, 0xd2, 0x4f, 0x16, 0x50, 0x24, 0x50, 0xf2, 0x4f, 0x00, 0x50, + 0x37, 0x50, 0x4e, 0x50, 0x5e, 0x50, 0x7c, 0x50, 0xab, 0x50, 0x69, 0x50, + 0xad, 0x4f, 0xa3, 0x4e, 0xe6, 0x4d, 0x42, 0x4d, 0xdc, 0x4c, 0x7c, 0x4c, + 0xbe, 0x4b, 0x08, 0x4b, 0x7b, 0x4a, 0xe4, 0x49, 0x14, 0x49, 0x07, 0x48, + 0x98, 0x46, 0x2f, 0x45, 0x16, 0x44, 0x23, 0x43, 0x55, 0x42, 0xac, 0x41, + 0x06, 0x41, 0x4b, 0x40, 0x8f, 0x3f, 0xde, 0x3e, 0xe1, 0x3d, 0x75, 0x3c, + 0xc0, 0x3a, 0xe4, 0x38, 0x83, 0x37, 0x9a, 0x36, 0xe5, 0x35, 0xc0, 0x34, + 0xf9, 0x32, 0xe1, 0x30, 0xfa, 0x2e, 0xd4, 0x2c, 0x4d, 0x2a, 0xed, 0x27, + 0xb9, 0x25, 0xb2, 0x23, 0x7d, 0x21, 0xfd, 0x1e, 0x89, 0x1c, 0x38, 0x1a, + 0xe2, 0x17, 0x67, 0x15, 0xf3, 0x12, 0xb3, 0x10, 0x9e, 0x0e, 0x79, 0x0c, + 0xea, 0x09, 0x54, 0x07, 0x26, 0x05, 0x0a, 0x03, 0xd7, 0x00, 0x98, 0xfe, + 0x41, 0xfc, 0x8d, 0xf9, 0x3c, 0xf7, 0x4f, 0xf5, 0x73, 0xf3, 0x7b, 0xf1, + 0x68, 0xef, 0x6f, 0xed, 0x7a, 0xeb, 0x87, 0xe9, 0x48, 0xe7, 0xc6, 0xe4, + 0x65, 0xe2, 0xf6, 0xdf, 0x86, 0xdd, 0x9f, 0xdb, 0x1b, 0xda, 0xa6, 0xd8, + 0xce, 0xd6, 0xe4, 0xd4, 0xe3, 0xd2, 0x84, 0xd0, 0xec, 0xcd, 0x08, 0xcc, + 0x89, 0xca, 0x1b, 0xc9, 0xe2, 0xc7, 0x9d, 0xc6, 0xe5, 0xc4, 0x79, 0xc3, + 0x6d, 0xc2, 0xe3, 0xc0, 0x3c, 0xbf, 0xd3, 0xbd, 0x41, 0xbc, 0xd2, 0xba, + 0x6a, 0xb9, 0xa1, 0xb7, 0xa9, 0xb5, 0x47, 0xb4, 0x91, 0xb3, 0xd5, 0xb2, + 0xb7, 0xb1, 0x51, 0xb0, 0x14, 0xaf, 0xf5, 0xad, 0x95, 0xac, 0x34, 0xab, + 0x05, 0xaa, 0xe1, 0xa8, 0xb3, 0xa7, 0xd9, 0xa6, 0x25, 0xa6, 0x6e, 0xa5, + 0x2b, 0xa5, 0x7b, 0xa5, 0x9a, 0xa5, 0x88, 0xa5, 0xc3, 0xa5, 0xe7, 0xa5, + 0xaf, 0xa5, 0x8b, 0xa5, 0x80, 0xa5, 0x65, 0xa5, 0x8c, 0xa5, 0x7e, 0xa5, + 0x22, 0xa5, 0x40, 0xa5, 0xed, 0xa5, 0x27, 0xa6, 0x2b, 0xa6, 0x1c, 0xa6, + 0xe5, 0xa5, 0x7b, 0xa5, 0x45, 0xa5, 0x37, 0xa5, 0x04, 0xa5, 0x91, 0xa4, + 0x8d, 0xa4, 0x2d, 0xa5, 0x9f, 0xa5, 0xf6, 0xa5, 0x7e, 0xa6, 0x34, 0xa7, + 0x14, 0xa8, 0x7e, 0xa8, 0x87, 0xa8, 0xc4, 0xa8, 0x51, 0xa9, 0xec, 0xa9, + 0x74, 0xaa, 0xf7, 0xaa, 0x40, 0xab, 0xd9, 0xab, 0xca, 0xac, 0x6b, 0xad, + 0xb3, 0xad, 0x08, 0xae, 0x10, 0xaf, 0x2c, 0xb0, 0xcb, 0xb0, 0x23, 0xb1, + 0xac, 0xb1, 0x0e, 0xb2, 0x42, 0xb2, 0xd7, 0xb2, 0xef, 0xb3, 0x21, 0xb5, + 0x30, 0xb6, 0xe9, 0xb6, 0x54, 0xb7, 0xf0, 0xb7, 0x9e, 0xb8, 0x2e, 0xb9, + 0x03, 0xba, 0x55, 0xbb, 0xdf, 0xbc, 0x5f, 0xbe, 0xb8, 0xbf, 0x01, 0xc1, + 0x83, 0xc2, 0x0c, 0xc4, 0x65, 0xc5, 0x7e, 0xc6, 0x86, 0xc7, 0xba, 0xc8, + 0x11, 0xca, 0x66, 0xcb, 0x28, 0xcd, 0x4d, 0xcf, 0x60, 0xd1, 0x69, 0xd3, + 0x7b, 0xd5, 0x5f, 0xd7, 0xe3, 0xd8, 0xca, 0xda, 0xda, 0xdc, 0xda, 0xde, + 0xab, 0xe0, 0x59, 0xe2, 0x3b, 0xe4, 0x21, 0xe6, 0xfc, 0xe7, 0xcb, 0xe9, + 0xbe, 0xeb, 0x9c, 0xed, 0x47, 0xef, 0x0b, 0xf1, 0xd3, 0xf2, 0xbc, 0xf4, + 0x9c, 0xf6, 0x67, 0xf8, 0x2a, 0xfa, 0xc1, 0xfb, 0x7f, 0xfd, 0x41, 0xff, + 0x12, 0x01, 0xd2, 0x02, 0xfc, 0x04, 0xe8, 0x06, 0x9a, 0x08, 0x59, 0x0a, + 0x48, 0x0c, 0x36, 0x0e, 0x37, 0x10, 0x36, 0x12, 0x59, 0x14, 0x62, 0x16, + 0x86, 0x18, 0xb9, 0x1a, 0xc2, 0x1c, 0xcd, 0x1e, 0xf1, 0x20, 0x27, 0x23, + 0x7a, 0x25, 0xf9, 0x27, 0x2a, 0x2a, 0x1f, 0x2c, 0xf8, 0x2d, 0xa3, 0x2f, + 0x23, 0x31, 0xf4, 0x32, 0x2c, 0x35, 0x40, 0x37, 0x23, 0x39, 0xfe, 0x3a, + 0x11, 0x3d, 0x2c, 0x3f, 0xe8, 0x40, 0x8c, 0x42, 0x55, 0x44, 0x37, 0x46, + 0x99, 0x47, 0xcb, 0x48, 0x12, 0x4a, 0x60, 0x4b, 0x86, 0x4c, 0x9b, 0x4d, + 0xc8, 0x4e, 0xec, 0x4f, 0xe3, 0x50, 0x8a, 0x51, 0x23, 0x52, 0xd8, 0x52, + 0x68, 0x53, 0x9b, 0x53, 0xb1, 0x53, 0x11, 0x54, 0x94, 0x54, 0xf7, 0x54, + 0x4f, 0x55, 0xa4, 0x55, 0x03, 0x56, 0x51, 0x56, 0x92, 0x56, 0xfa, 0x56, + 0x59, 0x57, 0xad, 0x57, 0xcd, 0x57, 0xc5, 0x57, 0xa8, 0x57, 0x64, 0x57, + 0x49, 0x57, 0x63, 0x57, 0x64, 0x57, 0x40, 0x57, 0xf6, 0x56, 0xfc, 0x56, + 0x36, 0x57, 0x3b, 0x57, 0x1e, 0x57, 0x1c, 0x57, 0x03, 0x57, 0xee, 0x56, + 0xa5, 0x56, 0x80, 0x56, 0xd4, 0x56, 0xe4, 0x56, 0x92, 0x56, 0xf0, 0x55, + 0x02, 0x55, 0xab, 0x53, 0xb5, 0x52, 0x51, 0x52, 0x08, 0x52, 0x80, 0x51, + 0xb4, 0x50, 0xde, 0x4f, 0x27, 0x4f, 0x63, 0x4e, 0x58, 0x4d, 0x72, 0x4c, + 0x82, 0x4b, 0x81, 0x4a, 0x87, 0x49, 0xb4, 0x48, 0xb1, 0x47, 0x99, 0x46, + 0xb4, 0x45, 0x34, 0x45, 0xb8, 0x44, 0x2f, 0x44, 0x7f, 0x43, 0xa0, 0x42, + 0xcb, 0x41, 0xd1, 0x40, 0xeb, 0x3f, 0x28, 0x3f, 0x3d, 0x3e, 0x09, 0x3d, + 0x9d, 0x3b, 0x40, 0x3a, 0x1c, 0x39, 0xeb, 0x37, 0xd1, 0x36, 0xb3, 0x35, + 0x8b, 0x34, 0x0b, 0x33, 0x51, 0x31, 0xfb, 0x2f, 0xb9, 0x2e, 0x54, 0x2d, + 0xaf, 0x2b, 0xdf, 0x29, 0xf1, 0x27, 0x3a, 0x26, 0x6f, 0x24, 0x56, 0x22, + 0x20, 0x20, 0x0a, 0x1e, 0x3b, 0x1c, 0x55, 0x1a, 0x6c, 0x18, 0xaa, 0x16, + 0xef, 0x14, 0x0a, 0x13, 0x17, 0x11, 0x1c, 0x0f, 0x22, 0x0d, 0x46, 0x0b, + 0x53, 0x09, 0x46, 0x07, 0x46, 0x05, 0x4d, 0x03, 0x1a, 0x01, 0xd3, 0xfe, + 0x94, 0xfc, 0x8c, 0xfa, 0x8f, 0xf8, 0xc1, 0xf6, 0x27, 0xf5, 0x8f, 0xf3, + 0xf2, 0xf1, 0x74, 0xf0, 0xfa, 0xee, 0x4d, 0xed, 0x9e, 0xeb, 0xa2, 0xe9, + 0x73, 0xe7, 0xa9, 0xe5, 0x2d, 0xe4, 0xa3, 0xe2, 0xf9, 0xe0, 0x50, 0xdf, + 0xb9, 0xdd, 0x34, 0xdc, 0xad, 0xda, 0x0b, 0xd9, 0x77, 0xd7, 0xb9, 0xd5, + 0x37, 0xd4, 0xff, 0xd2, 0x8a, 0xd1, 0x14, 0xd0, 0xba, 0xce, 0x7d, 0xcd, + 0x2c, 0xcc, 0xa1, 0xca, 0x22, 0xc9, 0xa9, 0xc7, 0x0e, 0xc6, 0x66, 0xc4, + 0xfc, 0xc2, 0xa5, 0xc1, 0x4a, 0xc0, 0xff, 0xbe, 0xf7, 0xbd, 0x0e, 0xbd, + 0x1d, 0xbc, 0x16, 0xbb, 0xad, 0xb9, 0x44, 0xb8, 0xd7, 0xb6, 0x9e, 0xb5, + 0x9f, 0xb4, 0x97, 0xb3, 0x72, 0xb2, 0x5f, 0xb1, 0x67, 0xb0, 0x89, 0xaf, + 0x9d, 0xae, 0xbe, 0xad, 0x08, 0xad, 0x5d, 0xac, 0x8b, 0xab, 0xad, 0xaa, + 0xe4, 0xa9, 0x59, 0xa9, 0xc4, 0xa8, 0x02, 0xa8, 0x4d, 0xa7, 0xc2, 0xa6, + 0x4a, 0xa6, 0x09, 0xa6, 0xd2, 0xa5, 0x50, 0xa5, 0xec, 0xa4, 0xc2, 0xa4, + 0xd9, 0xa4, 0xbd, 0xa4, 0x97, 0xa4, 0xa5, 0xa4, 0xbf, 0xa4, 0xb4, 0xa4, + 0x8f, 0xa4, 0x31, 0xa4, 0x39, 0xa4, 0x7d, 0xa4, 0xab, 0xa4, 0xc7, 0xa4, + 0xb3, 0xa4, 0xab, 0xa4, 0xca, 0xa4, 0x05, 0xa5, 0x1e, 0xa5, 0x2a, 0xa5, + 0x2c, 0xa5, 0x18, 0xa5, 0x01, 0xa5, 0x33, 0xa5, 0x8c, 0xa5, 0xb2, 0xa5, + 0x81, 0xa5, 0x5c, 0xa5, 0x6e, 0xa5, 0x79, 0xa5, 0x4e, 0xa5, 0x17, 0xa5, + 0xff, 0xa4, 0x1c, 0xa5, 0x45, 0xa5, 0x8a, 0xa5, 0xbf, 0xa5, 0xdb, 0xa5, + 0x41, 0xa6, 0xfb, 0xa6, 0xc6, 0xa7, 0x86, 0xa8, 0x29, 0xa9, 0x97, 0xa9, + 0x27, 0xaa, 0xd7, 0xaa, 0x6d, 0xab, 0xf4, 0xab, 0x34, 0xac, 0x69, 0xac, + 0xc6, 0xac, 0x37, 0xad, 0xaa, 0xad, 0x34, 0xae, 0xd3, 0xae, 0x81, 0xaf, + 0x16, 0xb0, 0x72, 0xb0, 0xc8, 0xb0, 0x36, 0xb1, 0x91, 0xb1, 0xe0, 0xb1, + 0x3b, 0xb2, 0x8e, 0xb2, 0xe0, 0xb2, 0x2a, 0xb3, 0xab, 0xb3, 0x3a, 0xb4, + 0xf1, 0xb4, 0xc0, 0xb5, 0xae, 0xb6, 0x91, 0xb7, 0x82, 0xb8, 0x98, 0xb9, + 0x8f, 0xba, 0x88, 0xbb, 0x65, 0xbc, 0x20, 0xbd, 0xcb, 0xbd, 0xaf, 0xbe, + 0x94, 0xbf, 0x84, 0xc0, 0x85, 0xc1, 0x7b, 0xc2, 0x67, 0xc3, 0x66, 0xc4, + 0x7f, 0xc5, 0x89, 0xc6, 0x6b, 0xc7, 0x38, 0xc8, 0x29, 0xc9, 0x4a, 0xca, + 0x82, 0xcb, 0xc1, 0xcc, 0x12, 0xce, 0x5e, 0xcf, 0xb0, 0xd0, 0x25, 0xd2, + 0x66, 0xd3, 0xde, 0xd4, 0x6c, 0xd6, 0x28, 0xd8, 0xd7, 0xd9, 0x80, 0xdb, + 0xf7, 0xdc, 0x6f, 0xde, 0xd0, 0xdf, 0x22, 0xe1, 0x7a, 0xe2, 0xe5, 0xe3, + 0x7a, 0xe5, 0xea, 0xe6, 0x51, 0xe8, 0xeb, 0xe9, 0x70, 0xeb, 0xb3, 0xec, + 0x01, 0xee, 0x60, 0xef, 0xcb, 0xf0, 0x1d, 0xf2, 0x7b, 0xf3, 0xcf, 0xf4, + 0x39, 0xf6, 0xc8, 0xf7, 0x82, 0xf9, 0x4a, 0xfb, 0xf2, 0xfc, 0x8c, 0xfe, + 0x01, 0x00, 0x68, 0x01, 0x15, 0x03, 0xe6, 0x04, 0xbc, 0x06, 0x42, 0x08, + 0xbb, 0x09, 0x2b, 0x0b, 0xc7, 0x0c, 0x35, 0x0e, 0x94, 0x0f, 0xf2, 0x10, + 0x59, 0x12, 0xbc, 0x13, 0x34, 0x15, 0xac, 0x16, 0x1c, 0x18, 0x79, 0x19, + 0xdc, 0x1a, 0x6d, 0x1c, 0x21, 0x1e, 0xca, 0x1f, 0x70, 0x21, 0x02, 0x23, + 0x6c, 0x24, 0x9e, 0x25, 0x45, 0x27, 0x02, 0x29, 0x95, 0x2a, 0xff, 0x2b, + 0x72, 0x2d, 0xe8, 0x2e, 0x48, 0x30, 0x7c, 0x31, 0xd2, 0x32, 0x3d, 0x34, + 0xac, 0x35, 0x26, 0x37, 0xbc, 0x38, 0x4c, 0x3a, 0x90, 0x3b, 0xef, 0x3c, + 0x61, 0x3e, 0xe8, 0x3f, 0x59, 0x41, 0xab, 0x42, 0xf7, 0x43, 0x2d, 0x45, + 0x6c, 0x46, 0x78, 0x47, 0xb4, 0x48, 0x2e, 0x4a, 0x8e, 0x4b, 0xd7, 0x4c, + 0xf4, 0x4d, 0xee, 0x4e, 0xcb, 0x4f, 0xc3, 0x50, 0xc2, 0x51, 0xac, 0x52, + 0x61, 0x53, 0xf3, 0x53, 0xac, 0x54, 0x5f, 0x55, 0xf4, 0x55, 0x7f, 0x56, + 0x04, 0x57, 0x9c, 0x57, 0x1f, 0x58, 0x7c, 0x58, 0xbc, 0x58, 0x0b, 0x59, + 0x71, 0x59, 0xc1, 0x59, 0x0b, 0x5a, 0x3e, 0x5a, 0x8b, 0x5a, 0xac, 0x5a, + 0xa9, 0x5a, 0x8a, 0x5a, 0x6c, 0x5a, 0x4c, 0x5a, 0x39, 0x5a, 0x32, 0x5a, + 0x40, 0x5a, 0x33, 0x5a, 0x44, 0x5a, 0x58, 0x5a, 0x79, 0x5a, 0x7a, 0x5a, + 0x69, 0x5a, 0x49, 0x5a, 0x54, 0x5a, 0x78, 0x5a, 0x72, 0x5a, 0x5f, 0x5a, + 0x31, 0x5a, 0x11, 0x5a, 0xf9, 0x59, 0xea, 0x59, 0xd1, 0x59, 0xa1, 0x59, + 0x48, 0x59, 0xf0, 0x58, 0xa2, 0x58, 0x6e, 0x58, 0x60, 0x58, 0x46, 0x58, + 0x3f, 0x58, 0x47, 0x58, 0x40, 0x58, 0x08, 0x58, 0x9c, 0x57, 0x11, 0x57, + 0x83, 0x56, 0xd7, 0x55, 0x42, 0x55, 0xab, 0x54, 0x06, 0x54, 0x63, 0x53, + 0xa6, 0x52, 0xf0, 0x51, 0x55, 0x51, 0xbc, 0x50, 0x1e, 0x50, 0x8e, 0x4f, + 0xf3, 0x4e, 0x34, 0x4e, 0x6b, 0x4d, 0xc9, 0x4c, 0x30, 0x4c, 0x7d, 0x4b, + 0xd8, 0x4a, 0x49, 0x4a, 0xad, 0x49, 0x11, 0x49, 0x6c, 0x48, 0xa4, 0x47, + 0xec, 0x46, 0x6c, 0x46, 0xde, 0x45, 0x5d, 0x45, 0xbc, 0x44, 0xf1, 0x43, + 0x34, 0x43, 0x8c, 0x42, 0xf8, 0x41, 0x47, 0x41, 0x6a, 0x40, 0x72, 0x3f, + 0x8b, 0x3e, 0xb3, 0x3d, 0xf2, 0x3c, 0x2f, 0x3c, 0x5c, 0x3b, 0x96, 0x3a, + 0xbc, 0x39, 0xb2, 0x38, 0x91, 0x37, 0x8c, 0x36, 0x75, 0x35, 0x63, 0x34, + 0x5e, 0x33, 0x63, 0x32, 0x4b, 0x31, 0x3c, 0x30, 0x1e, 0x2f, 0x07, 0x2e, + 0xd0, 0x2c, 0xb2, 0x2b, 0x84, 0x2a, 0x4d, 0x29, 0xfc, 0x27, 0xa5, 0x26, + 0x2f, 0x25, 0x95, 0x23, 0x1f, 0x22, 0xad, 0x20, 0x3a, 0x1f, 0x9e, 0x1d, + 0x10, 0x1c, 0x6e, 0x1a, 0xe3, 0x18, 0x56, 0x17, 0xdb, 0x15, 0x58, 0x14, + 0xba, 0x12, 0x2a, 0x11, 0x8b, 0x0f, 0xf4, 0x0d, 0x5b, 0x0c, 0xd3, 0x0a, + 0x5f, 0x09, 0xe5, 0x07, 0x4a, 0x06, 0xc0, 0x04, 0x3e, 0x03, 0xb6, 0x01, + 0x37, 0x00, 0xca, 0xfe, 0x74, 0xfd, 0x00, 0xfc, 0xa5, 0xfa, 0x4a, 0xf9, + 0xd1, 0xf7, 0x7e, 0xf6, 0x1c, 0xf5, 0x9d, 0xf3, 0x4f, 0xf2, 0x0e, 0xf1, + 0xc0, 0xef, 0x3a, 0xee, 0xd8, 0xec, 0x69, 0xeb, 0x0c, 0xea, 0xad, 0xe8, + 0x56, 0xe7, 0xf8, 0xe5, 0xbe, 0xe4, 0x98, 0xe3, 0x61, 0xe2, 0x03, 0xe1, + 0x99, 0xdf, 0x4d, 0xde, 0x0e, 0xdd, 0xde, 0xdb, 0xad, 0xda, 0x84, 0xd9, + 0x62, 0xd8, 0x32, 0xd7, 0x01, 0xd6, 0xb7, 0xd4, 0x87, 0xd3, 0x97, 0xd2, + 0x89, 0xd1, 0x89, 0xd0, 0x6e, 0xcf, 0x65, 0xce, 0x5d, 0xcd, 0x44, 0xcc, + 0x13, 0xcb, 0xf2, 0xc9, 0xd3, 0xc8, 0xad, 0xc7, 0x9b, 0xc6, 0x94, 0xc5, + 0x8e, 0xc4, 0x7b, 0xc3, 0x92, 0xc2, 0xad, 0xc1, 0xb2, 0xc0, 0xb9, 0xbf, + 0xb3, 0xbe, 0xc0, 0xbd, 0xd5, 0xbc, 0xf2, 0xbb, 0xe1, 0xba, 0xc7, 0xb9, + 0xc7, 0xb8, 0xe8, 0xb7, 0x09, 0xb7, 0x2c, 0xb6, 0x66, 0xb5, 0xb1, 0xb4, + 0xf6, 0xb3, 0x32, 0xb3, 0x53, 0xb2, 0x92, 0xb1, 0xdb, 0xb0, 0x0d, 0xb0, + 0x46, 0xaf, 0x62, 0xae, 0x98, 0xad, 0xd1, 0xac, 0x3f, 0xac, 0xb0, 0xab, + 0x34, 0xab, 0xb1, 0xaa, 0x45, 0xaa, 0xda, 0xa9, 0x6a, 0xa9, 0xf1, 0xa8, + 0x7d, 0xa8, 0x04, 0xa8, 0xbb, 0xa7, 0x80, 0xa7, 0x41, 0xa7, 0x02, 0xa7, + 0xb6, 0xa6, 0x68, 0xa6, 0x3b, 0xa6, 0x1c, 0xa6, 0x0d, 0xa6, 0xfc, 0xa5, + 0xd4, 0xa5, 0xa6, 0xa5, 0x81, 0xa5, 0x76, 0xa5, 0x61, 0xa5, 0x54, 0xa5, + 0x48, 0xa5, 0x47, 0xa5, 0x4b, 0xa5, 0x49, 0xa5, 0x38, 0xa5, 0x4b, 0xa5, + 0x6c, 0xa5, 0xa3, 0xa5, 0xda, 0xa5, 0xfe, 0xa5, 0x21, 0xa6, 0x4a, 0xa6, + 0x8a, 0xa6, 0xb4, 0xa6, 0xe0, 0xa6, 0xf3, 0xa6, 0x1b, 0xa7, 0x17, 0xa7, + 0x40, 0xa7, 0x8e, 0xa7, 0xcd, 0xa7, 0x06, 0xa8, 0x3e, 0xa8, 0x86, 0xa8, + 0xbd, 0xa8, 0xde, 0xa8, 0xf6, 0xa8, 0x1c, 0xa9, 0x49, 0xa9, 0x5c, 0xa9, + 0x79, 0xa9, 0x93, 0xa9, 0xab, 0xa9, 0xe6, 0xa9, 0x2c, 0xaa, 0x82, 0xaa, + 0xbc, 0xaa, 0xec, 0xaa, 0x32, 0xab, 0x69, 0xab, 0xa7, 0xab, 0xde, 0xab, + 0x19, 0xac, 0x53, 0xac, 0xbb, 0xac, 0x14, 0xad, 0x8a, 0xad, 0xeb, 0xad, + 0x6c, 0xae, 0xe1, 0xae, 0x62, 0xaf, 0xd9, 0xaf, 0x58, 0xb0, 0xc0, 0xb0, + 0x36, 0xb1, 0x99, 0xb1, 0x11, 0xb2, 0x71, 0xb2, 0xdc, 0xb2, 0x58, 0xb3, + 0xbb, 0xb3, 0x37, 0xb4, 0xb6, 0xb4, 0x46, 0xb5, 0xca, 0xb5, 0x50, 0xb6, + 0xd9, 0xb6, 0x6c, 0xb7, 0x03, 0xb8, 0x7e, 0xb8, 0xf0, 0xb8, 0x64, 0xb9, + 0xcf, 0xb9, 0x47, 0xba, 0xd3, 0xba, 0x60, 0xbb, 0xe8, 0xbb, 0x70, 0xbc, + 0xf3, 0xbc, 0x82, 0xbd, 0x05, 0xbe, 0xa1, 0xbe, 0x2a, 0xbf, 0xae, 0xbf, + 0x25, 0xc0, 0xac, 0xc0, 0x52, 0xc1, 0xde, 0xc1, 0x75, 0xc2, 0x11, 0xc3, + 0xb5, 0xc3, 0x42, 0xc4, 0xc5, 0xc4, 0x6d, 0xc5, 0x0b, 0xc6, 0xb2, 0xc6, + 0x4b, 0xc7, 0xf6, 0xc7, 0x9b, 0xc8, 0x4f, 0xc9, 0x17, 0xca, 0xf3, 0xca, + 0xc6, 0xcb, 0x9a, 0xcc, 0x7b, 0xcd, 0x54, 0xce, 0x32, 0xcf, 0x09, 0xd0, + 0xd7, 0xd0, 0xc9, 0xd1, 0xc1, 0xd2, 0xb8, 0xd3, 0xb6, 0xd4, 0xae, 0xd5, + 0xbc, 0xd6, 0xca, 0xd7, 0xd2, 0xd8, 0xca, 0xd9, 0xbd, 0xda, 0xc8, 0xdb, + 0xd8, 0xdc, 0xf9, 0xdd, 0x08, 0xdf, 0x1e, 0xe0, 0x39, 0xe1, 0x4e, 0xe2, + 0x60, 0xe3, 0x7a, 0xe4, 0x96, 0xe5, 0xc1, 0xe6, 0xde, 0xe7, 0x0e, 0xe9, + 0x2a, 0xea, 0x42, 0xeb, 0x7a, 0xec, 0x9f, 0xed, 0xbb, 0xee, 0xd6, 0xef, + 0xef, 0xf0, 0x0e, 0xf2, 0x30, 0xf3, 0x55, 0xf4, 0x68, 0xf5, 0x7e, 0xf6, + 0xa4, 0xf7, 0xc0, 0xf8, 0xea, 0xf9, 0x10, 0xfb, 0x41, 0xfc, 0x7d, 0xfd, + 0xad, 0xfe, 0xe3, 0xff, 0x10, 0x01, 0x27, 0x02, 0x58, 0x03, 0x74, 0x04, + 0xa4, 0x05, 0xd5, 0x06, 0x0b, 0x08, 0x36, 0x09, 0x5c, 0x0a, 0x76, 0x0b, + 0x9a, 0x0c, 0xc1, 0x0d, 0xd8, 0x0e, 0xf5, 0x0f, 0x15, 0x11, 0x3f, 0x12, + 0x70, 0x13, 0x8e, 0x14, 0xcc, 0x15, 0xf2, 0x16, 0x31, 0x18, 0x4b, 0x19, + 0x82, 0x1a, 0xa1, 0x1b, 0xbc, 0x1c, 0xde, 0x1d, 0xe9, 0x1e, 0x13, 0x20, + 0x33, 0x21, 0x6c, 0x22, 0x80, 0x23, 0xa7, 0x24, 0xbc, 0x25, 0xde, 0x26, + 0xe7, 0x27, 0x07, 0x29, 0x28, 0x2a, 0x36, 0x2b, 0x4d, 0x2c, 0x71, 0x2d, + 0x91, 0x2e, 0xbe, 0x2f, 0xd6, 0x30, 0xfb, 0x31, 0x20, 0x33, 0x46, 0x34, + 0x59, 0x35, 0x7a, 0x36, 0xa1, 0x37, 0xc2, 0x38, 0xdf, 0x39, 0x01, 0x3b, + 0x0f, 0x3c, 0x27, 0x3d, 0x1f, 0x3e, 0x2e, 0x3f, 0x43, 0x40, 0x5b, 0x41, + 0x73, 0x42, 0x8e, 0x43, 0xaf, 0x44, 0xbc, 0x45, 0xcc, 0x46, 0xd8, 0x47, + 0xec, 0x48, 0xe1, 0x49, 0xd1, 0x4a, 0xc4, 0x4b, 0xb6, 0x4c, 0xa9, 0x4d, + 0x9d, 0x4e, 0x88, 0x4f, 0x75, 0x50, 0x4c, 0x51, 0x3b, 0x52, 0x05, 0x53, + 0xd9, 0x53, 0xa1, 0x54, 0x6f, 0x55, 0x33, 0x56, 0xe5, 0x56, 0x7d, 0x57, + 0x15, 0x58, 0xb3, 0x58, 0x4e, 0x59, 0xdb, 0x59, 0x55, 0x5a, 0xc8, 0x5a, + 0x36, 0x5b, 0xa9, 0x5b, 0x09, 0x5c, 0x5a, 0x5c, 0xab, 0x5c, 0xf1, 0x5c, + 0x34, 0x5d, 0x6a, 0x5d, 0x9e, 0x5d, 0xc1, 0x5d, 0xea, 0x5d, 0x0b, 0x5e, + 0x28, 0x5e, 0x3d, 0x5e, 0x41, 0x5e, 0x51, 0x5e, 0x5f, 0x5e, 0x69, 0x5e, + 0x79, 0x5e, 0x6a, 0x5e, 0x78, 0x5e, 0x76, 0x5e, 0x7f, 0x5e, 0x72, 0x5e, + 0x70, 0x5e, 0x61, 0x5e, 0x61, 0x5e, 0x42, 0x5e, 0x36, 0x5e, 0x2f, 0x5e, + 0x2c, 0x5e, 0x1a, 0x5e, 0xec, 0x5d, 0xbf, 0x5d, 0x94, 0x5d, 0x71, 0x5d, + 0x4c, 0x5d, 0x24, 0x5d, 0xfa, 0x5c, 0xc3, 0x5c, 0x8c, 0x5c, 0x59, 0x5c, + 0x3e, 0x5c, 0x0c, 0x5c, 0xd3, 0x5b, 0xb1, 0x5b, 0x78, 0x5b, 0x45, 0x5b, + 0x14, 0x5b, 0xed, 0x5a, 0xc0, 0x5a, 0x89, 0x5a, 0x4f, 0x5a, 0x16, 0x5a, + 0xe5, 0x59, 0xb5, 0x59, 0x84, 0x59, 0x4e, 0x59, 0x0d, 0x59, 0xcf, 0x58, + 0xa6, 0x58, 0x79, 0x58, 0x3e, 0x58, 0xf8, 0x57, 0xc0, 0x57, 0x83, 0x57, + 0x38, 0x57, 0x03, 0x57, 0xc1, 0x56, 0x65, 0x56, 0xe0, 0x55, 0x52, 0x55, + 0xd0, 0x54, 0x4c, 0x54, 0xbe, 0x53, 0x32, 0x53, 0xa7, 0x52, 0x2a, 0x52, + 0x95, 0x51, 0x09, 0x51, 0x76, 0x50, 0xe9, 0x4f, 0x69, 0x4f, 0xe2, 0x4e, + 0x49, 0x4e, 0xc0, 0x4d, 0x38, 0x4d, 0xbd, 0x4c, 0x2d, 0x4c, 0x98, 0x4b, + 0x07, 0x4b, 0x76, 0x4a, 0xdc, 0x49, 0x4a, 0x49, 0xb9, 0x48, 0x2d, 0x48, + 0x9c, 0x47, 0x19, 0x47, 0x80, 0x46, 0xf9, 0x45, 0x66, 0x45, 0xd6, 0x44, + 0x47, 0x44, 0xb5, 0x43, 0x14, 0x43, 0x74, 0x42, 0xd4, 0x41, 0x42, 0x41, + 0xa4, 0x40, 0x18, 0x40, 0x85, 0x3f, 0xeb, 0x3e, 0x52, 0x3e, 0xb2, 0x3d, + 0x0c, 0x3d, 0x7a, 0x3c, 0xdb, 0x3b, 0x3a, 0x3b, 0x87, 0x3a, 0xe0, 0x39, + 0x29, 0x39, 0x88, 0x38, 0xd1, 0x37, 0x16, 0x37, 0x4d, 0x36, 0x9e, 0x35, + 0xdc, 0x34, 0x19, 0x34, 0x4a, 0x33, 0x83, 0x32, 0xb7, 0x31, 0xec, 0x30, + 0x1c, 0x30, 0x47, 0x2f, 0x71, 0x2e, 0x88, 0x2d, 0xa6, 0x2c, 0xbb, 0x2b, + 0xd0, 0x2a, 0xd8, 0x29, 0xdb, 0x28, 0xe3, 0x27, 0xf5, 0x26, 0xf1, 0x25, + 0xf8, 0x24, 0xdc, 0x23, 0xdb, 0x22, 0xca, 0x21, 0xa7, 0x20, 0x85, 0x1f, + 0x5a, 0x1e, 0x30, 0x1d, 0x0a, 0x1c, 0xd5, 0x1a, 0xa6, 0x19, 0x6d, 0x18, + 0x3d, 0x17, 0xff, 0x15, 0xbf, 0x14, 0x81, 0x13, 0x57, 0x12, 0x15, 0x11, + 0xe0, 0x0f, 0xa2, 0x0e, 0x65, 0x0d, 0x27, 0x0c, 0xf1, 0x0a, 0xb2, 0x09, + 0x77, 0x08, 0x4b, 0x07, 0x0a, 0x06, 0xc9, 0x04, 0x97, 0x03, 0x65, 0x02, + 0x3b, 0x01, 0x03, 0x00, 0xd2, 0xfe, 0x95, 0xfd, 0x6f, 0xfc, 0x50, 0xfb, + 0x19, 0xfa, 0xf0, 0xf8, 0xb8, 0xf7, 0x97, 0xf6, 0x65, 0xf5, 0x48, 0xf4, + 0x24, 0xf3, 0xfe, 0xf1, 0xec, 0xf0, 0xd2, 0xef, 0xa9, 0xee, 0x95, 0xed, + 0x76, 0xec, 0x64, 0xeb, 0x61, 0xea, 0x43, 0xe9, 0x3a, 0xe8, 0x21, 0xe7, + 0x14, 0xe6, 0xff, 0xe4, 0x06, 0xe4, 0x04, 0xe3, 0x04, 0xe2, 0x01, 0xe1, + 0x02, 0xe0, 0x04, 0xdf, 0x16, 0xde, 0x1f, 0xdd, 0x29, 0xdc, 0x2d, 0xdb, + 0x3d, 0xda, 0x45, 0xd9, 0x5a, 0xd8, 0x6f, 0xd7, 0x74, 0xd6, 0x8a, 0xd5, + 0x91, 0xd4, 0xa5, 0xd3, 0xbb, 0xd2, 0xdb, 0xd1, 0x01, 0xd1, 0x17, 0xd0, + 0x42, 0xcf, 0x5e, 0xce, 0x94, 0xcd, 0xb1, 0xcc, 0xe8, 0xcb, 0x04, 0xcb, + 0x29, 0xca, 0x4e, 0xc9, 0x78, 0xc8, 0x99, 0xc7, 0xc4, 0xc6, 0xff, 0xc5, + 0x3d, 0xc5, 0x76, 0xc4, 0xa6, 0xc3, 0xe4, 0xc2, 0x17, 0xc2, 0x4e, 0xc1, + 0x8a, 0xc0, 0xc5, 0xbf, 0x0b, 0xbf, 0x42, 0xbe, 0x8e, 0xbd, 0xd8, 0xbc, + 0x20, 0xbc, 0x60, 0xbb, 0xbb, 0xba, 0x08, 0xba, 0x5a, 0xb9, 0xba, 0xb8, + 0x08, 0xb8, 0x64, 0xb7, 0xb1, 0xb6, 0x0c, 0xb6, 0x5d, 0xb5, 0xbf, 0xb4, + 0x10, 0xb4, 0x7b, 0xb3, 0xd0, 0xb2, 0x3d, 0xb2, 0xa1, 0xb1, 0x0f, 0xb1, + 0x84, 0xb0, 0xf2, 0xaf, 0x63, 0xaf, 0xd3, 0xae, 0x50, 0xae, 0xbd, 0xad, + 0x49, 0xad, 0xc1, 0xac, 0x4d, 0xac, 0xc6, 0xab, 0x56, 0xab, 0xe4, 0xaa, + 0x83, 0xaa, 0x0d, 0xaa, 0xac, 0xa9, 0x49, 0xa9, 0xf3, 0xa8, 0x9e, 0xa8, + 0x4e, 0xa8, 0x07, 0xa8, 0xc5, 0xa7, 0x8d, 0xa7, 0x56, 0xa7, 0x1d, 0xa7, + 0xf6, 0xa6, 0xc7, 0xa6, 0xad, 0xa6, 0x8c, 0xa6, 0x74, 0xa6, 0x58, 0xa6, + 0x47, 0xa6, 0x2d, 0xa6, 0x24, 0xa6, 0x23, 0xa6, 0x21, 0xa6, 0x19, 0xa6, + 0x20, 0xa6, 0x1f, 0xa6, 0x28, 0xa6, 0x3c, 0xa6, 0x4e, 0xa6, 0x59, 0xa6, + 0x6e, 0xa6, 0x84, 0xa6, 0x9a, 0xa6, 0xb7, 0xa6, 0xd4, 0xa6, 0xef, 0xa6, + 0x0a, 0xa7, 0x2f, 0xa7, 0x53, 0xa7, 0x77, 0xa7, 0x9c, 0xa7, 0xbc, 0xa7, + 0xe5, 0xa7, 0x10, 0xa8, 0x35, 0xa8, 0x6d, 0xa8, 0x9b, 0xa8, 0xcb, 0xa8, + 0xf5, 0xa8, 0x23, 0xa9, 0x5a, 0xa9, 0x80, 0xa9, 0xb7, 0xa9, 0xee, 0xa9, + 0x1c, 0xaa, 0x46, 0xaa, 0x78, 0xaa, 0xb2, 0xaa, 0xeb, 0xaa, 0x1a, 0xab, + 0x57, 0xab, 0x84, 0xab, 0xba, 0xab, 0xef, 0xab, 0x22, 0xac, 0x55, 0xac, + 0x88, 0xac, 0xc1, 0xac, 0xf5, 0xac, 0x2a, 0xad, 0x67, 0xad, 0x9f, 0xad, + 0xe0, 0xad, 0x14, 0xae, 0x4c, 0xae, 0x82, 0xae, 0xb8, 0xae, 0xf8, 0xae, + 0x2c, 0xaf, 0x6a, 0xaf, 0x9d, 0xaf, 0xd4, 0xaf, 0x05, 0xb0, 0x38, 0xb0, + 0x77, 0xb0, 0xb2, 0xb0, 0xf8, 0xb0, 0x3c, 0xb1, 0x97, 0xb1, 0x05, 0xb2, + 0x6f, 0xb2, 0xdf, 0xb2, 0x48, 0xb3, 0xb2, 0xb3, 0x16, 0xb4, 0x7b, 0xb4, + 0xe5, 0xb4, 0x54, 0xb5, 0xc3, 0xb5, 0x26, 0xb6, 0x97, 0xb6, 0x03, 0xb7, + 0x68, 0xb7, 0xce, 0xb7, 0x44, 0xb8, 0xae, 0xb8, 0x20, 0xb9, 0x87, 0xb9, + 0xf1, 0xb9, 0x5d, 0xba, 0xc6, 0xba, 0x24, 0xbb, 0xa1, 0xbb, 0x05, 0xbc, + 0x79, 0xbc, 0xdc, 0xbc, 0x4b, 0xbd, 0xba, 0xbd, 0x24, 0xbe, 0x9b, 0xbe, + 0x07, 0xbf, 0x72, 0xbf, 0xe5, 0xbf, 0x46, 0xc0, 0xc3, 0xc0, 0x1f, 0xc1, + 0x91, 0xc1, 0x01, 0xc2, 0x79, 0xc2, 0xf1, 0xc2, 0x66, 0xc3, 0xe5, 0xc3, + 0x55, 0xc4, 0xc8, 0xc4, 0x3e, 0xc5, 0xb3, 0xc5, 0x2d, 0xc6, 0xa7, 0xc6, + 0x27, 0xc7, 0x97, 0xc7, 0x1f, 0xc8, 0xa0, 0xc8, 0x29, 0xc9, 0xad, 0xc9, + 0x36, 0xca, 0xad, 0xca, 0x3d, 0xcb, 0xc0, 0xcb, 0x47, 0xcc, 0xe9, 0xcc, + 0x6f, 0xcd, 0x06, 0xce, 0x84, 0xce, 0x1a, 0xcf, 0xbb, 0xcf, 0x55, 0xd0, + 0xf6, 0xd0, 0x8b, 0xd1, 0x30, 0xd2, 0xd2, 0xd2, 0x79, 0xd3, 0x1c, 0xd4, + 0xcf, 0xd4, 0x83, 0xd5, 0x36, 0xd6, 0xe1, 0xd6, 0x96, 0xd7, 0x5f, 0xd8, + 0x1c, 0xd9, 0xe2, 0xd9, 0xa8, 0xda, 0x6c, 0xdb, 0x43, 0xdc, 0x04, 0xdd, + 0xd8, 0xdd, 0xac, 0xde, 0x8a, 0xdf, 0x5b, 0xe0, 0x39, 0xe1, 0x0b, 0xe2, + 0xf5, 0xe2, 0xde, 0xe3, 0xbc, 0xe4, 0x9e, 0xe5, 0x83, 0xe6, 0x62, 0xe7, + 0x51, 0xe8, 0x34, 0xe9, 0x1e, 0xea, 0x12, 0xeb, 0xf7, 0xeb, 0xe5, 0xec, + 0xc5, 0xed, 0xc2, 0xee, 0xb1, 0xef, 0xa6, 0xf0, 0x90, 0xf1, 0x7e, 0xf2, + 0x6f, 0xf3, 0x56, 0xf4, 0x48, 0xf5, 0x35, 0xf6, 0x29, 0xf7, 0x17, 0xf8, + 0x0a, 0xf9, 0x00, 0xfa, 0xe7, 0xfa, 0xde, 0xfb, 0xc9, 0xfc, 0xc1, 0xfd, + 0xac, 0xfe, 0xae, 0xff, 0xa2, 0x00, 0x8d, 0x01, 0x70, 0x02, 0x62, 0x03, + 0x4e, 0x04, 0x3a, 0x05, 0x26, 0x06, 0x16, 0x07, 0xff, 0x07, 0xf3, 0x08, + 0xda, 0x09, 0xbe, 0x0a, 0xb9, 0x0b, 0xa1, 0x0c, 0x9b, 0x0d, 0x7d, 0x0e, + 0x66, 0x0f, 0x54, 0x10, 0x36, 0x11, 0x20, 0x12, 0x11, 0x13, 0xf3, 0x13, + 0xea, 0x14, 0xd1, 0x15, 0xb6, 0x16, 0x9b, 0x17, 0x83, 0x18, 0x7f, 0x19, + 0x58, 0x1a, 0x53, 0x1b, 0x37, 0x1c, 0x22, 0x1d, 0x0a, 0x1e, 0xf3, 0x1e, + 0xda, 0x1f, 0xca, 0x20, 0xb1, 0x21, 0x96, 0x22, 0x70, 0x23, 0x55, 0x24, + 0x39, 0x25, 0x39, 0x26, 0x1a, 0x27, 0x07, 0x28, 0xe1, 0x28, 0xc5, 0x29, + 0xa7, 0x2a, 0x85, 0x2b, 0x70, 0x2c, 0x4e, 0x2d, 0x3e, 0x2e, 0x19, 0x2f, + 0xf3, 0x2f, 0xdf, 0x30, 0xc0, 0x31, 0xaf, 0x32, 0x93, 0x33, 0x77, 0x34, + 0x48, 0x35, 0x2a, 0x36, 0x0f, 0x37, 0xf8, 0x37, 0xd9, 0x38, 0xbe, 0x39, + 0x8b, 0x3a, 0x74, 0x3b, 0x48, 0x3c, 0x2d, 0x3d, 0xfa, 0x3d, 0xe7, 0x3e, + 0xb0, 0x3f, 0x98, 0x40, 0x67, 0x41, 0x3a, 0x42, 0x16, 0x43, 0xf4, 0x43, + 0xd8, 0x44, 0xa4, 0x45, 0x7c, 0x46, 0x4c, 0x47, 0x2a, 0x48, 0x06, 0x49, + 0xce, 0x49, 0xa5, 0x4a, 0x77, 0x4b, 0x4e, 0x4c, 0x13, 0x4d, 0xdf, 0x4d, + 0xaa, 0x4e, 0x74, 0x4f, 0x3d, 0x50, 0xfc, 0x50, 0xbd, 0x51, 0x8c, 0x52, + 0x3e, 0x53, 0xfe, 0x53, 0x99, 0x54, 0x57, 0x55, 0xfc, 0x55, 0xab, 0x56, + 0x45, 0x57, 0xd6, 0x57, 0x87, 0x58, 0x2f, 0x59, 0xbf, 0x59, 0x48, 0x5a, + 0xc7, 0x5a, 0x54, 0x5b, 0xc8, 0x5b, 0x45, 0x5c, 0xb4, 0x5c, 0x25, 0x5d, + 0x7e, 0x5d, 0xda, 0x5d, 0x36, 0x5e, 0xa5, 0x5e, 0xe9, 0x5e, 0x37, 0x5f, + 0x72, 0x5f, 0xab, 0x5f, 0xe5, 0x5f, 0x1d, 0x60, 0x4f, 0x60, 0x81, 0x60, + 0x9c, 0x60, 0xc3, 0x60, 0xdc, 0x60, 0xf7, 0x60, 0x04, 0x61, 0x16, 0x61, + 0x1b, 0x61, 0x21, 0x61, 0x20, 0x61, 0x0d, 0x61, 0x0b, 0x61, 0xf0, 0x60, + 0xe5, 0x60, 0xc7, 0x60, 0xb3, 0x60, 0x98, 0x60, 0x7c, 0x60, 0x59, 0x60, + 0x4c, 0x60, 0x24, 0x60, 0x0d, 0x60, 0xdf, 0x5f, 0xb7, 0x5f, 0x87, 0x5f, + 0x6b, 0x5f, 0x44, 0x5f, 0x28, 0x5f, 0xf5, 0x5e, 0xbd, 0x5e, 0x8f, 0x5e, + 0x5c, 0x5e, 0x2a, 0x5e, 0xfe, 0x5d, 0xcd, 0x5d, 0xa4, 0x5d, 0x75, 0x5d, + 0x4d, 0x5d, 0x11, 0x5d, 0xdf, 0x5c, 0xa9, 0x5c, 0x78, 0x5c, 0x42, 0x5c, + 0x13, 0x5c, 0xde, 0x5b, 0xaf, 0x5b, 0x75, 0x5b, 0x3e, 0x5b, 0xfd, 0x5a, + 0xbc, 0x5a, 0x90, 0x5a, 0x54, 0x5a, 0x1f, 0x5a, 0xe5, 0x59, 0xc2, 0x59, + 0x80, 0x59, 0x39, 0x59, 0x0a, 0x59, 0xd6, 0x58, 0x96, 0x58, 0x55, 0x58, + 0x1e, 0x58, 0xf1, 0x57, 0xc8, 0x57, 0x7e, 0x57, 0x44, 0x57, 0x11, 0x57, + 0xd4, 0x56, 0x93, 0x56, 0x4c, 0x56, 0x11, 0x56, 0xd7, 0x55, 0xae, 0x55, + 0x72, 0x55, 0x3c, 0x55, 0x0c, 0x55, 0xd1, 0x54, 0x98, 0x54, 0x63, 0x54, + 0x2b, 0x54, 0xf8, 0x53, 0xc6, 0x53, 0x81, 0x53, 0x4b, 0x53, 0x19, 0x53, + 0xea, 0x52, 0xb2, 0x52, 0x7e, 0x52, 0x30, 0x52, 0xc5, 0x51, 0x46, 0x51, + 0xca, 0x50, 0x55, 0x50, 0xd7, 0x4f, 0x5d, 0x4f, 0xe4, 0x4e, 0x79, 0x4e, + 0xfb, 0x4d, 0x83, 0x4d, 0x02, 0x4d, 0x8a, 0x4c, 0x1f, 0x4c, 0x98, 0x4b, + 0x20, 0x4b, 0xa7, 0x4a, 0x36, 0x4a, 0xc0, 0x49, 0x44, 0x49, 0xc3, 0x48, + 0x44, 0x48, 0xd5, 0x47, 0x59, 0x47, 0xe6, 0x46, 0x63, 0x46, 0xf8, 0x45, + 0x79, 0x45, 0xfa, 0x44, 0x80, 0x44, 0x01, 0x44, 0x7a, 0x43, 0x04, 0x43, + 0x85, 0x42, 0x07, 0x42, 0x92, 0x41, 0x17, 0x41, 0x94, 0x40, 0x16, 0x40, + 0x9f, 0x3f, 0x20, 0x3f, 0x9c, 0x3e, 0x29, 0x3e, 0x9c, 0x3d, 0x20, 0x3d, + 0x88, 0x3c, 0x0c, 0x3c, 0x87, 0x3b, 0x07, 0x3b, 0x89, 0x3a, 0xfb, 0x39, + 0x6f, 0x39, 0xe7, 0x38, 0x55, 0x38, 0xcf, 0x37, 0x43, 0x37, 0xb5, 0x36, + 0x2a, 0x36, 0x9c, 0x35, 0x0a, 0x35, 0x83, 0x34, 0xe6, 0x33, 0x53, 0x33, + 0xba, 0x32, 0x1d, 0x32, 0x78, 0x31, 0xcb, 0x30, 0x34, 0x30, 0x8e, 0x2f, + 0xf6, 0x2e, 0x56, 0x2e, 0xab, 0x2d, 0xfe, 0x2c, 0x4c, 0x2c, 0x9f, 0x2b, + 0xed, 0x2a, 0x36, 0x2a, 0x7b, 0x29, 0xb9, 0x28, 0x02, 0x28, 0x41, 0x27, + 0x81, 0x26, 0xb9, 0x25, 0xfb, 0x24, 0x2d, 0x24, 0x66, 0x23, 0x98, 0x22, + 0xc6, 0x21, 0xe9, 0x20, 0x0d, 0x20, 0x28, 0x1f, 0x4c, 0x1e, 0x64, 0x1d, + 0x66, 0x1c, 0x8c, 0x1b, 0x96, 0x1a, 0xac, 0x19, 0xb2, 0x18, 0xbb, 0x17, + 0xc2, 0x16, 0xc7, 0x15, 0xcb, 0x14, 0xcd, 0x13, 0xc4, 0x12, 0xca, 0x11, + 0xb6, 0x10, 0xb8, 0x0f, 0xa3, 0x0e, 0x9e, 0x0d, 0x88, 0x0c, 0x86, 0x0b, + 0x7b, 0x0a, 0x7c, 0x09, 0x6d, 0x08, 0x5b, 0x07, 0x4a, 0x06, 0x38, 0x05, + 0x2f, 0x04, 0x1c, 0x03, 0x10, 0x02, 0xf6, 0x00, 0xe9, 0xff, 0xe5, 0xfe, + 0xcf, 0xfd, 0xc8, 0xfc, 0xb1, 0xfb, 0xa7, 0xfa, 0x8d, 0xf9, 0x7b, 0xf8, + 0x7e, 0xf7, 0x77, 0xf6, 0x68, 0xf5, 0x62, 0xf4, 0x49, 0xf3, 0x42, 0xf2, + 0x41, 0xf1, 0x3e, 0xf0, 0x49, 0xef, 0x47, 0xee, 0x56, 0xed, 0x46, 0xec, + 0x56, 0xeb, 0x5c, 0xea, 0x6c, 0xe9, 0x7d, 0xe8, 0x9c, 0xe7, 0x99, 0xe6, + 0xbf, 0xe5, 0xc9, 0xe4, 0xe5, 0xe3, 0xfd, 0xe2, 0x17, 0xe2, 0x26, 0xe1, + 0x44, 0xe0, 0x6d, 0xdf, 0x9f, 0xde, 0xc5, 0xdd, 0xec, 0xdc, 0x26, 0xdc, + 0x58, 0xdb, 0x91, 0xda, 0xb7, 0xd9, 0xf5, 0xd8, 0x27, 0xd8, 0x63, 0xd7, + 0x96, 0xd6, 0xd5, 0xd5, 0x1a, 0xd5, 0x52, 0xd4, 0x9d, 0xd3, 0xde, 0xd2, + 0x27, 0xd2, 0x6c, 0xd1, 0xb3, 0xd0, 0xf6, 0xcf, 0x51, 0xcf, 0x98, 0xce, + 0xe9, 0xcd, 0x2f, 0xcd, 0x88, 0xcc, 0xdc, 0xcb, 0x41, 0xcb, 0x9f, 0xca, + 0x01, 0xca, 0x60, 0xc9, 0xc4, 0xc8, 0x13, 0xc8, 0x7e, 0xc7, 0xe2, 0xc6, + 0x51, 0xc6, 0xb6, 0xc5, 0x1a, 0xc5, 0x8e, 0xc4, 0xf6, 0xc3, 0x74, 0xc3, + 0xdf, 0xc2, 0x59, 0xc2, 0xd2, 0xc1, 0x47, 0xc1, 0xbe, 0xc0, 0x3b, 0xc0, + 0xbe, 0xbf, 0x3e, 0xbf, 0xc4, 0xbe, 0x39, 0xbe, 0xbf, 0xbd, 0x3e, 0xbd, + 0xd7, 0xbc, 0x5d, 0xbc, 0xec, 0xbb, 0x73, 0xbb, 0x07, 0xbb, 0x96, 0xba, + 0x24, 0xba, 0xb5, 0xb9, 0x49, 0xb9, 0xdd, 0xb8, 0x76, 0xb8, 0x02, 0xb8, + 0xa8, 0xb7, 0x3c, 0xb7, 0xee, 0xb6, 0x82, 0xb6, 0x2b, 0xb6, 0xc3, 0xb5, + 0x6e, 0xb5, 0x14, 0xb5, 0xc4, 0xb4, 0x6b, 0xb4, 0x20, 0xb4, 0xd2, 0xb3, + 0x78, 0xb3, 0x2c, 0xb3, 0xe6, 0xb2, 0x9e, 0xb2, 0x58, 0xb2, 0x1a, 0xb2, + 0xea, 0xb1, 0xa6, 0xb1, 0x63, 0xb1, 0x2b, 0xb1, 0xf3, 0xb0, 0xb8, 0xb0, + 0x7b, 0xb0, 0x4e, 0xb0, 0x20, 0xb0, 0xf9, 0xaf, 0xc6, 0xaf, 0xa2, 0xaf, + 0x84, 0xaf, 0x5e, 0xaf, 0x44, 0xaf, 0x21, 0xaf, 0x06, 0xaf, 0xe9, 0xae, + 0xe2, 0xae, 0xd0, 0xae, 0xc3, 0xae, 0xba, 0xae, 0xc1, 0xae, 0xaf, 0xae, + 0xbc, 0xae, 0xb5, 0xae, 0xc0, 0xae, 0xc3, 0xae, 0xd7, 0xae, 0xdd, 0xae, + 0xfb, 0xae, 0x0a, 0xaf, 0x16, 0xaf, 0x37, 0xaf, 0x4a, 0xaf, 0x70, 0xaf, + 0x86, 0xaf, 0xa9, 0xaf, 0xc7, 0xaf, 0xec, 0xaf, 0x12, 0xb0, 0x42, 0xb0, + 0x66, 0xb0, 0x91, 0xb0, 0xc0, 0xb0, 0xee, 0xb0, 0x1a, 0xb1, 0x4c, 0xb1, + 0x77, 0xb1, 0xb3, 0xb1, 0xdd, 0xb1, 0x10, 0xb2, 0x47, 0xb2, 0x70, 0xb2, + 0xb8, 0xb2, 0xef, 0xb2, 0x26, 0xb3, 0x64, 0xb3, 0x90, 0xb3, 0xd8, 0xb3, + 0x07, 0xb4, 0x4b, 0xb4, 0x83, 0xb4, 0xc7, 0xb4, 0xf4, 0xb4, 0x35, 0xb5, + 0x70, 0xb5, 0xbc, 0xb5, 0xf0, 0xb5, 0x39, 0xb6, 0x7d, 0xb6, 0xb7, 0xb6, + 0xfa, 0xb6, 0x2e, 0xb7, 0x7d, 0xb7, 0xbb, 0xb7, 0x01, 0xb8, 0x39, 0xb8, + 0x80, 0xb8, 0xbd, 0xb8, 0x05, 0xb9, 0x46, 0xb9, 0x94, 0xb9, 0xcd, 0xb9, + 0x17, 0xba, 0x5b, 0xba, 0x9e, 0xba, 0xdf, 0xba, 0x27, 0xbb, 0x6a, 0xbb, + 0xbc, 0xbb, 0xf6, 0xbb, 0x3a, 0xbc, 0x83, 0xbc, 0xc3, 0xbc, 0x16, 0xbd, + 0x58, 0xbd, 0xa2, 0xbd, 0xe0, 0xbd, 0x24, 0xbe, 0x70, 0xbe, 0xa1, 0xbe, + 0xfa, 0xbe, 0x37, 0xbf, 0x8d, 0xbf, 0xc9, 0xbf, 0x1d, 0xc0, 0x5d, 0xc0, + 0xa6, 0xc0, 0xe6, 0xc0, 0x2f, 0xc1, 0x7a, 0xc1, 0xcb, 0xc1, 0x2f, 0xc2, + 0x95, 0xc2, 0xfa, 0xc2, 0x55, 0xc3, 0xbb, 0xc3, 0x1e, 0xc4, 0x86, 0xc4, + 0xec, 0xc4, 0x4b, 0xc5, 0xab, 0xc5, 0x04, 0xc6, 0x72, 0xc6, 0xc6, 0xc6, + 0x3a, 0xc7, 0x8e, 0xc7, 0xfd, 0xc7, 0x5a, 0xc8, 0xc0, 0xc8, 0x17, 0xc9, + 0x79, 0xc9, 0xd5, 0xc9, 0x43, 0xca, 0x98, 0xca, 0x05, 0xcb, 0x64, 0xcb, + 0xc3, 0xcb, 0x1e, 0xcc, 0x81, 0xcc, 0xe3, 0xcc, 0x40, 0xcd, 0xa6, 0xcd, + 0x0a, 0xce, 0x6a, 0xce, 0xc0, 0xce, 0x26, 0xcf, 0x81, 0xcf, 0xf0, 0xcf, + 0x48, 0xd0, 0xad, 0xd0, 0x07, 0xd1, 0x71, 0xd1, 0xca, 0xd1, 0x2b, 0xd2, + 0x8a, 0xd2, 0xed, 0xd2, 0x50, 0xd3, 0xa1, 0xd3, 0x0f, 0xd4, 0x6f, 0xd4, + 0xd6, 0xd4, 0x30, 0xd5, 0x93, 0xd5, 0xf6, 0xd5, 0x55, 0xd6, 0xb5, 0xd6, + 0x12, 0xd7, 0x7b, 0xd7, 0xde, 0xd7, 0x34, 0xd8, 0x93, 0xd8, 0xe9, 0xd8, + 0x61, 0xd9, 0xbb, 0xd9, 0x2b, 0xda, 0x88, 0xda, 0xeb, 0xda, 0x4f, 0xdb, + 0xb9, 0xdb, 0x21, 0xdc, 0x80, 0xdc, 0xf7, 0xdc, 0x53, 0xdd, 0xbb, 0xdd, + 0x2b, 0xde, 0xa4, 0xde, 0x05, 0xdf, 0x74, 0xdf, 0xd8, 0xdf, 0x44, 0xe0, + 0xb4, 0xe0, 0x26, 0xe1, 0x91, 0xe1, 0x01, 0xe2, 0x77, 0xe2, 0xeb, 0xe2, + 0x5e, 0xe3, 0xc7, 0xe3, 0x44, 0xe4, 0xb2, 0xe4, 0x25, 0xe5, 0xa3, 0xe5, + 0x15, 0xe6, 0x97, 0xe6, 0x0b, 0xe7, 0x8b, 0xe7, 0x10, 0xe8, 0x7d, 0xe8, + 0x06, 0xe9, 0x74, 0xe9, 0xff, 0xe9, 0x82, 0xea, 0x01, 0xeb, 0x85, 0xeb, + 0xfa, 0xeb, 0x91, 0xec, 0x07, 0xed, 0x8f, 0xed, 0x15, 0xee, 0x9a, 0xee, + 0x26, 0xef, 0xa5, 0xef, 0x26, 0xf0, 0xb2, 0xf0, 0x3e, 0xf1, 0xca, 0xf1, + 0x45, 0xf2, 0xcc, 0xf2, 0x51, 0xf3, 0xdc, 0xf3, 0x5c, 0xf4, 0xe8, 0xf4, + 0x6e, 0xf5, 0xf9, 0xf5, 0x79, 0xf6, 0xf9, 0xf6, 0x7d, 0xf7, 0x08, 0xf8, + 0x91, 0xf8, 0x18, 0xf9, 0x95, 0xf9, 0x18, 0xfa, 0xa5, 0xfa, 0x21, 0xfb, + 0xa9, 0xfb, 0x2a, 0xfc, 0xa7, 0xfc, 0x23, 0xfd, 0xa3, 0xfd, 0x2b, 0xfe, + 0x9c, 0xfe, 0x2b, 0xff, 0xa0, 0xff, 0x1c, 0x00, 0x9a, 0x00, 0x11, 0x01, + 0x9a, 0x01, 0x14, 0x02, 0x8c, 0x02, 0x07, 0x03, 0x84, 0x03, 0xf7, 0x03, + 0x75, 0x04, 0xf3, 0x04, 0x65, 0x05, 0xe8, 0x05, 0x54, 0x06, 0xd3, 0x06, + 0x48, 0x07, 0xc2, 0x07, 0x38, 0x08, 0xad, 0x08, 0x28, 0x09, 0x99, 0x09, + 0x11, 0x0a, 0x79, 0x0a, 0xf5, 0x0a, 0x5c, 0x0b, 0xd1, 0x0b, 0x3f, 0x0c, + 0xb5, 0x0c, 0x2c, 0x0d, 0x9a, 0x0d, 0x0b, 0x0e, 0x74, 0x0e, 0xe6, 0x0e, + 0x45, 0x0f, 0xbd, 0x0f, 0x2f, 0x10, 0x9a, 0x10, 0x05, 0x11, 0x6c, 0x11, + 0xdb, 0x11, 0x40, 0x12, 0xaa, 0x12, 0x14, 0x13, 0x81, 0x13, 0xe9, 0x13, + 0x4d, 0x14, 0xb9, 0x14, 0x18, 0x15, 0x88, 0x15, 0xe6, 0x15, 0x58, 0x16, + 0xb9, 0x16, 0x1c, 0x17, 0x7e, 0x17, 0xe3, 0x17, 0x43, 0x18, 0xac, 0x18, + 0x08, 0x19, 0x6d, 0x19, 0xce, 0x19, 0x34, 0x1a, 0x90, 0x1a, 0xf5, 0x1a, + 0x53, 0x1b, 0xbb, 0x1b, 0x07, 0x1c, 0x6f, 0x1c, 0xc2, 0x1c, 0x28, 0x1d, + 0x84, 0x1d, 0xe8, 0x1d, 0x35, 0x1e, 0xa2, 0x1e, 0xf8, 0x1e, 0x59, 0x1f, + 0xb8, 0x1f, 0x0c, 0x20, 0x69, 0x20, 0xbe, 0x20, 0x19, 0x21, 0x66, 0x21, + 0xc6, 0x21, 0x1f, 0x22, 0x70, 0x22, 0xbe, 0x22, 0x18, 0x23, 0x72, 0x23, + 0xbf, 0x23, 0x0f, 0x24, 0x67, 0x24, 0xc0, 0x24, 0x08, 0x25, 0x51, 0x25, + 0xa6, 0x25, 0xf4, 0x25, 0x42, 0x26, 0x93, 0x26, 0xd6, 0x26, 0x25, 0x27, + 0x6c, 0x27, 0xb7, 0x27, 0x07, 0x28, 0x49, 0x28, 0x96, 0x28, 0xda, 0x28, + 0x22, 0x29, 0x66, 0x29, 0xa4, 0x29, 0xe8, 0x29, 0x20, 0x2a, 0x62, 0x2a, + 0xa9, 0x2a, 0xe5, 0x2a, 0x21, 0x2b, 0x5a, 0x2b, 0x97, 0x2b, 0xc1, 0x2b, + 0xfe, 0x2b, 0x28, 0x2c, 0x57, 0x2c, 0x88, 0x2c, 0xae, 0x2c, 0xd3, 0x2c, + 0xfa, 0x2c, 0x17, 0x2d, 0x33, 0x2d, 0x4b, 0x2d, 0x5d, 0x2d, 0x68, 0x2d, + 0x81, 0x2d, 0x92, 0x2d, 0x9e, 0x2d, 0xa9, 0x2d, 0xbb, 0x2d, 0xc3, 0x2d, + 0xcd, 0x2d, 0xd5, 0x2d, 0xcd, 0x2d, 0xdc, 0x2d, 0xe3, 0x2d, 0xe1, 0x2d, + 0xdd, 0x2d, 0xd9, 0x2d, 0xd7, 0x2d, 0xcf, 0x2d, 0xe0, 0x2d, 0xd2, 0x2d, + 0xd2, 0x2d, 0xcb, 0x2d, 0xb7, 0x2d, 0xb6, 0x2d, 0xa1, 0x2d, 0x9e, 0x2d, + 0x8b, 0x2d, 0x84, 0x2d, 0x68, 0x2d, 0x6a, 0x2d, 0x4e, 0x2d, 0x45, 0x2d, + 0x2f, 0x2d, 0x18, 0x2d, 0x15, 0x2d, 0xef, 0x2c, 0xe8, 0x2c, 0xc9, 0x2c, + 0xc7, 0x2c, 0xaa, 0x2c, 0x9b, 0x2c, 0x7c, 0x2c, 0x64, 0x2c, 0x3c, 0x2c, + 0x2e, 0x2c, 0x16, 0x2c, 0x05, 0x2c, 0xe1, 0x2b, 0xc8, 0x2b, 0xb5, 0x2b, + 0x9a, 0x2b, 0x7c, 0x2b, 0x61, 0x2b, 0x3f, 0x2b, 0x21, 0x2b, 0x01, 0x2b, + 0xee, 0x2a, 0xd0, 0x2a, 0xb3, 0x2a, 0x95, 0x2a, 0x6d, 0x2a, 0x50, 0x2a, + 0x2b, 0x2a, 0x0b, 0x2a, 0xe9, 0x29, 0xd1, 0x29, 0xa8, 0x29, 0x97, 0x29, + 0x6c, 0x29, 0x51, 0x29, 0x24, 0x29, 0x03, 0x29, 0xe6, 0x28, 0xbe, 0x28, + 0xa1, 0x28, 0x80, 0x28, 0x64, 0x28, 0x38, 0x28, 0x12, 0x28, 0xf0, 0x27, + 0xd3, 0x27, 0xac, 0x27, 0x94, 0x27, 0x67, 0x27, 0x4a, 0x27, 0x1c, 0x27, + 0xf7, 0x26, 0xd1, 0x26, 0xb6, 0x26, 0x8d, 0x26, 0x6e, 0x26, 0x4b, 0x26, + 0x25, 0x26, 0x02, 0x26, 0xd8, 0x25, 0xbe, 0x25, 0x93, 0x25, 0x7c, 0x25, + 0x4a, 0x25, 0x27, 0x25, 0x07, 0x25, 0xdc, 0x24, 0xbb, 0x24, 0x9a, 0x24, + 0x78, 0x24, 0x4c, 0x24, 0x26, 0x24, 0x00, 0x24, 0xd7, 0x23, 0xc0, 0x23, + 0x94, 0x23, 0x71, 0x23, 0x45, 0x23, 0x1c, 0x23, 0x00, 0x23, 0xd4, 0x22, + 0xb5, 0x22, 0x8e, 0x22, 0x67, 0x22, 0x39, 0x22, 0x00, 0x22, 0xbd, 0x21, + 0x87, 0x21, 0x46, 0x21, 0x01, 0x21, 0xca, 0x20, 0x89, 0x20, 0x4a, 0x20, + 0x17, 0x20, 0xd6, 0x1f, 0x9a, 0x1f, 0x5e, 0x1f, 0x20, 0x1f, 0xe0, 0x1e, + 0xa3, 0x1e, 0x5f, 0x1e, 0x29, 0x1e, 0xf0, 0x1d, 0xb8, 0x1d, 0x78, 0x1d, + 0x36, 0x1d, 0x04, 0x1d, 0xc6, 0x1c, 0x8b, 0x1c, 0x4d, 0x1c, 0x18, 0x1c, + 0xd9, 0x1b, 0x97, 0x1b, 0x5c, 0x1b, 0x2b, 0x1b, 0xf4, 0x1a, 0xb1, 0x1a, + 0x7c, 0x1a, 0x32, 0x1a, 0x02, 0x1a, 0xc6, 0x19, 0x8b, 0x19, 0x59, 0x19, + 0x10, 0x19, 0xd7, 0x18, 0x9c, 0x18, 0x62, 0x18, 0x22, 0x18, 0xe8, 0x17, + 0xb1, 0x17, 0x7c, 0x17, 0x34, 0x17, 0xf9, 0x16, 0xc0, 0x16, 0x8b, 0x16, + 0x55, 0x16, 0x14, 0x16, 0xdd, 0x15, 0x9f, 0x15, 0x65, 0x15, 0x2b, 0x15, + 0xea, 0x14, 0xb9, 0x14, 0x70, 0x14, 0x3d, 0x14, 0x05, 0x14, 0xc1, 0x13, + 0x86, 0x13, 0x45, 0x13, 0x09, 0x13, 0xca, 0x12, 0x90, 0x12, 0x57, 0x12, + 0x1a, 0x12, 0xe1, 0x11, 0x9b, 0x11, 0x61, 0x11, 0x1d, 0x11, 0xe1, 0x10, + 0x9d, 0x10, 0x64, 0x10, 0x17, 0x10, 0xde, 0x0f, 0xa1, 0x0f, 0x60, 0x0f, + 0x1b, 0x0f, 0xd8, 0x0e, 0x90, 0x0e, 0x5b, 0x0e, 0x0e, 0x0e, 0xd3, 0x0d, + 0x86, 0x0d, 0x4d, 0x0d, 0xf5, 0x0c, 0xba, 0x0c, 0x68, 0x0c, 0x2a, 0x0c, + 0xde, 0x0b, 0x94, 0x0b, 0x4e, 0x0b, 0x07, 0x0b, 0xbb, 0x0a, 0x6c, 0x0a, + 0x25, 0x0a, 0xd4, 0x09, 0x89, 0x09, 0x39, 0x09, 0xe6, 0x08, 0xa3, 0x08, + 0x4f, 0x08, 0x02, 0x08, 0xa7, 0x07, 0x5f, 0x07, 0x08, 0x07, 0xba, 0x06, + 0x68, 0x06, 0x1f, 0x06, 0xc5, 0x05, 0x7a, 0x05, 0x1f, 0x05, 0xd7, 0x04, + 0x85, 0x04, 0x31, 0x04, 0xde, 0x03, 0x89, 0x03, 0x3a, 0x03, 0xe9, 0x02, + 0x96, 0x02, 0x47, 0x02, 0xf7, 0x01, 0xa4, 0x01, 0x5d, 0x01, 0x06, 0x01, + 0xb9, 0x00, 0x00, 0x00 +}; +unsigned int kick_raw_len = 6352; diff --git a/third-party/TeensyVariablePlayback/extras/soundio/save_raw_sd/CMakeLists.txt b/third-party/TeensyVariablePlayback/extras/soundio/save_raw_sd/CMakeLists.txt new file mode 100644 index 0000000..02f6b47 --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/soundio/save_raw_sd/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.10) +set(CMAKE_CXX_STANDARD 11) +project(save_raw_sd) + +find_package(teensy_x86_stubs) +include_directories(${teensy_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_x86_sd_stubs) +include_directories(${teensy_x86_sd_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs) +include_directories(${teensy_audio_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs_soundio) +if(teensy_audio_x86_stubs_soundio_FOUND) + include_directories(${teensy_audio_x86_stubs_soundio_INCLUDE_DIR}) + + include_directories(../../../src) + include_directories(/usr/local/include) #soundio + + add_executable(save_raw_sd save_raw_sd.cpp) + target_link_libraries(save_raw_sd teensy_variable_playback) + + if(WIN32) + elseif(UNIX AND NOT APPLE) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") + SET(SOUNDIO_LIBS -L/usr/lib/x86_64-linux-gnu -lsoundio) + elseif(APPLE) + INCLUDE_DIRECTORIES(/System/Library/Frameworks) + FIND_LIBRARY(glfw3_LIBRARY glfw) + FIND_LIBRARY(COCOA_LIBRARY Cocoa) + FIND_LIBRARY(OpenGL_LIBRARY OpenGL) + FIND_LIBRARY(IOKit_LIBRARY IOKit) + FIND_LIBRARY(glew_LIBRARY glew) + FIND_LIBRARY(CoreVideo_LIBRARY CoreVideo) + MARK_AS_ADVANCED(COCOA_LIBRARY OpenGL_LIBRARY) + FIND_LIBRARY(FREETYPE_LIBRARIES FreeType) + SET(APPLE_LIBS ${COCOA_LIBRARY} ${IOKit_LIBRARY} ${OpenGL_LIBRARY} ${CoreVideo_LIBRARY}) + SET(APPLE_LIBS ${APPLE_LIBS} ${GLFW3_LIBRARY} ${ASSIMP_LIBRARY} ${FREETYPE_LIBRARIES} ${glfw3_LIBRARY} ${glew_LIBRARY}) + set(LIBS ${LIBS} ${APPLE_LIBS}) + target_link_libraries(save_raw_sd + "-framework CoreServices" + "-framework CoreAudio" + "-framework Foundation" + "-framework AudioUnit") + SET(SOUNDIO_LIBS /usr/local/lib/libsoundio.a) + endif() + + target_link_libraries(save_raw_sd ${LIBS} ${teensy_x86_stubs_LIBS} ${teensy_x86_sd_stubs_LIBS} ${teensy_audio_x86_stubs_LIBS} ${teensy_audio_x86_stubs_soundio_LIBS} ${teensy_st7735_linux_stubs_LIBS} ${teensy_st7735_linux_extras_opengl_LIBS} ${SOUNDIO_LIBS}) + #set(CMAKE_VERBOSE_MAKEFILE 1) +endif() \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/extras/soundio/save_raw_sd/save_raw_sd.cpp b/third-party/TeensyVariablePlayback/extras/soundio/save_raw_sd/save_raw_sd.cpp new file mode 100644 index 0000000..5741e71 --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/soundio/save_raw_sd/save_raw_sd.cpp @@ -0,0 +1,701 @@ +// Plays a RAW (16-bit signed) PCM audio file at slower or faster rate +// this example plays a sample stored in an array +#include +#include +#include "playsdresmp.h" +#include "output_soundio.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// GUItool: begin automatically generated code +AudioPlaySdResmp playSdRaw1; //xy=306,225 +AudioRecordQueue queue1; //xy=609,267 +AudioOutputSoundIO sio_out1; //xy=612,224 +AudioConnection patchCord1(playSdRaw1, 0, sio_out1, 0); +AudioConnection patchCord2(playSdRaw1, 0, sio_out1, 1); +AudioConnection patchCord3(playSdRaw1, 0, queue1, 0); +// GUItool: end automatically generated code + +const char *_filename = "KICK.RAW"; +extern unsigned int kick_raw_len; +extern unsigned char kick_raw[]; + +int16_t buffer[512] = {0}; +File frec; + +unsigned long lastSamplePlayed = 0; +void my_handler(sig_atomic_t i); +static char stack_body[64*1024]; +static stack_t sigseg_stack; +static struct sigaction sigseg_handler; + +void crash_handler(sig_atomic_t i); + +void setup() { + Serial.begin(9600); + + playSdRaw1.setPlaybackRate(1.4f); + playSdRaw1.enableInterpolation(true); + //rraw_a1.play((int16_t*)kick_raw, kick_raw_len/2); + Serial.println("setup done"); + + if (SD.exists("RECORD_SD.RAW")) { + // The SD library writes new data to the end of the + // file, so to start a new recording, the old file + // must be deleted before new data is written. + SD.remove("RECORD_SD.RAW"); + } + frec = SD.open("RECORD_SD.RAW", O_WRITE); + + AudioMemory(120); + + if (frec) { + queue1.begin(); + Serial.println("startRecording"); + } else { + Serial.println("recording failed..."); + } +} + +void loop() { + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 1000) { + if (!playSdRaw1.isPlaying()) { + playSdRaw1.playRaw(_filename, 1); + lastSamplePlayed = currentMillis; + + Serial.print("Memory: "); + Serial.print(AudioMemoryUsage()); + Serial.print(","); + Serial.print(AudioMemoryUsageMax()); + Serial.println(); + } + } + + if (queue1.available() >= 1) { + int16_t* incomming = queue1.readBuffer(); + //Serial.printf("sizeof(incomming)=%i\n", sizeof(incomming)); + //if (incomming != NULL && sizeof(incomming) >= 256) { + if (incomming != NULL) { + memcpy(buffer, incomming, 256); + queue1.freeBuffer(); + frec.write((unsigned char *)buffer, 256); + frec.flush(); + } + //else { + // arduino_should_exit = true; + //Serial.printf("sizeof(incomming)=%i\n", sizeof(incomming)); + //} + } + delay(1); +} + +int main(int numArgs, char **args) { + + if (numArgs < 2) + { + std::cout << "usage: " << args[0] << " "; + exit(0); + } + std::cout << args[1] << std::endl; + signal (SIGINT,my_handler); + signal (SIGSEGV,crash_handler); + + sigseg_stack.ss_sp = stack_body; + sigseg_stack.ss_flags = SS_ONSTACK; + sigseg_stack.ss_size = sizeof(stack_body); + // assert(!sigaltstack(&sigseg_stack, nullptr)); + sigseg_handler.sa_flags = SA_ONSTACK; + sigseg_handler.sa_handler = &crash_handler; + // assert(!sigaction(SIGSEGV, &sigseg_handler, nullptr)); + + initialize_mock_arduino(); + //SD.setSDCardFileData((char *) kick_raw, kick_raw_len); + SD.setSDCardFolderPath(args[1]); + setup(); + while(!arduino_should_exit){ + loop(); + } + delay(1000); + frec.close(); +} + +void my_handler(sig_atomic_t i){ + if ( i== SIGINT) { + arduino_should_exit = true; + printf("Caught signal %d\n",i); + } else + { + cerr << "sig seg fault handler" << endl; + const int asize = 10; + void *array[asize]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, asize); + + // print out all the frames to stderr + cerr << "stack trace: " << endl; + backtrace_symbols_fd(array, size, STDERR_FILENO); + cerr << "resend SIGSEGV to get core dump" << endl; + signal(i, SIG_DFL); + kill(getpid(), i); + } +} +void crash_handler(sig_atomic_t i){ + cerr << "sig seg fault handler" << endl; + const int asize = 10; + void *array[asize]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, asize); + + // print out all the frames to stderr + cerr << "stack trace: " << endl; + backtrace_symbols_fd(array, size, STDERR_FILENO); + cerr << "resend SIGSEGV to get core dump" << endl; + signal(i, SIG_DFL); + kill(getpid(), i); +} + +unsigned char kick_raw[] = { + 0x99, 0x02, 0xd7, 0x02, 0xfa, 0x02, 0x5f, 0x03, 0xc1, 0x03, 0x2a, 0x04, + 0xad, 0x04, 0xa5, 0x05, 0x76, 0x06, 0x2f, 0x07, 0x9e, 0x07, 0xe2, 0x07, + 0x43, 0x08, 0x92, 0x08, 0xb2, 0x08, 0xe8, 0x08, 0x16, 0x09, 0xda, 0x08, + 0x51, 0x08, 0x01, 0x08, 0x25, 0x08, 0x70, 0x08, 0xc3, 0x08, 0x23, 0x09, + 0x95, 0x09, 0x19, 0x0a, 0x83, 0x0a, 0x7e, 0x0a, 0xd0, 0x0a, 0x65, 0x0b, + 0xf6, 0x0b, 0x89, 0x0c, 0xd1, 0x0c, 0xcf, 0x0c, 0x1a, 0x0d, 0xe5, 0x0d, + 0x5e, 0x0e, 0xbb, 0x0e, 0xec, 0x0e, 0xd9, 0x0e, 0x07, 0x0f, 0xc8, 0x0f, + 0x2a, 0x10, 0x04, 0x10, 0x28, 0x10, 0x54, 0x11, 0x8e, 0x13, 0x4b, 0x16, + 0x09, 0x19, 0x91, 0x1b, 0xf7, 0x1d, 0x55, 0x20, 0xd1, 0x22, 0xcb, 0x25, + 0x4d, 0x29, 0xa8, 0x2c, 0x7f, 0x2f, 0xda, 0x31, 0xac, 0x34, 0x0a, 0x3a, + 0x24, 0x47, 0x9d, 0x5b, 0xe9, 0x67, 0x29, 0x67, 0x24, 0x66, 0x26, 0x66, + 0xd2, 0x65, 0x9c, 0x65, 0x38, 0x65, 0x05, 0x65, 0x9f, 0x64, 0x64, 0x64, + 0x12, 0x64, 0xce, 0x63, 0x7c, 0x63, 0x32, 0x63, 0xe6, 0x62, 0x97, 0x62, + 0x49, 0x62, 0x01, 0x62, 0xb3, 0x61, 0x63, 0x61, 0x15, 0x61, 0xc4, 0x60, + 0x75, 0x60, 0x20, 0x60, 0xce, 0x5f, 0x7a, 0x5f, 0x28, 0x5f, 0xd5, 0x5e, + 0x81, 0x5e, 0x2d, 0x5e, 0xd3, 0x5d, 0x80, 0x5d, 0x2e, 0x5d, 0xe6, 0x5c, + 0x1a, 0x5c, 0x16, 0x5a, 0x01, 0x58, 0xb9, 0x56, 0x6d, 0x55, 0xf4, 0x53, + 0x49, 0x52, 0x83, 0x50, 0x87, 0x4e, 0x5f, 0x4c, 0x68, 0x4a, 0x5c, 0x48, + 0x62, 0x46, 0x5a, 0x44, 0xe2, 0x41, 0x08, 0x3f, 0x1c, 0x3c, 0x44, 0x39, + 0x35, 0x36, 0xcb, 0x32, 0xaf, 0x2f, 0xc8, 0x2c, 0xf8, 0x29, 0x55, 0x27, + 0x6a, 0x24, 0x0f, 0x21, 0x5e, 0x1d, 0xc3, 0x19, 0x7b, 0x16, 0x71, 0x13, + 0x6c, 0x10, 0x00, 0x0d, 0xd2, 0x08, 0x7f, 0x04, 0x7a, 0x01, 0x43, 0xff, + 0xb9, 0xfc, 0xfa, 0xf9, 0x3b, 0xf7, 0xcb, 0xf4, 0x2b, 0xf2, 0x02, 0xef, + 0x0c, 0xec, 0x3d, 0xe9, 0x21, 0xe6, 0xa6, 0xe2, 0x8a, 0xdf, 0x00, 0xdd, + 0xbc, 0xda, 0x9e, 0xd8, 0xc1, 0xd6, 0xd6, 0xd4, 0xd6, 0xd2, 0xad, 0xd0, + 0x5f, 0xce, 0xf0, 0xcb, 0xe9, 0xc9, 0x61, 0xc8, 0x75, 0xc7, 0x97, 0xc6, + 0x3e, 0xc5, 0x07, 0xc4, 0x8e, 0xc3, 0x18, 0xc3, 0x3a, 0xc2, 0x15, 0xc1, + 0x0e, 0xc0, 0xb3, 0xbf, 0xcf, 0xbf, 0xf8, 0xbf, 0xcc, 0xbf, 0x72, 0xbf, + 0x41, 0xbf, 0x2b, 0xbf, 0xe2, 0xbe, 0x99, 0xbe, 0x4e, 0xbe, 0x0e, 0xbe, + 0xcd, 0xbd, 0x7c, 0xbd, 0x8a, 0xbd, 0x88, 0xbd, 0x04, 0xbd, 0x0c, 0xbc, + 0xb3, 0xbb, 0xf6, 0xbb, 0xf1, 0xbb, 0x12, 0xbc, 0x6f, 0xbc, 0xcb, 0xbc, + 0xe4, 0xbc, 0x33, 0xbd, 0x1b, 0xbe, 0xac, 0xbe, 0x1e, 0xbf, 0x91, 0xbf, + 0x50, 0xc0, 0x40, 0xc1, 0x3d, 0xc2, 0x32, 0xc3, 0xdf, 0xc3, 0xad, 0xc4, + 0x77, 0xc5, 0xbe, 0xc6, 0xc7, 0xc8, 0x1d, 0xcb, 0x0e, 0xcd, 0x83, 0xce, + 0xf1, 0xcf, 0xb4, 0xd1, 0x7d, 0xd3, 0x86, 0xd5, 0x89, 0xd7, 0xd2, 0xd9, + 0x34, 0xdc, 0x28, 0xde, 0x23, 0xe0, 0x33, 0xe2, 0x0a, 0xe4, 0x59, 0xe5, + 0xfc, 0xe6, 0x98, 0xe9, 0x30, 0xec, 0x91, 0xee, 0xc2, 0xf0, 0x0d, 0xf3, + 0x35, 0xf5, 0xf3, 0xf6, 0xc4, 0xf8, 0xcb, 0xfa, 0xef, 0xfc, 0x65, 0xff, + 0x05, 0x02, 0x7c, 0x04, 0xde, 0x06, 0x75, 0x09, 0x2b, 0x0c, 0x9b, 0x0e, + 0xf3, 0x10, 0xb3, 0x13, 0x3a, 0x16, 0xeb, 0x18, 0x55, 0x1c, 0xad, 0x1f, + 0xa8, 0x22, 0x54, 0x25, 0xae, 0x27, 0x33, 0x2a, 0x16, 0x2d, 0x36, 0x30, + 0x84, 0x33, 0x94, 0x36, 0xbd, 0x38, 0xa2, 0x3a, 0x7d, 0x3c, 0x06, 0x3e, + 0x24, 0x3f, 0x27, 0x40, 0x7c, 0x41, 0xef, 0x42, 0x14, 0x44, 0xeb, 0x44, + 0x06, 0x46, 0x53, 0x47, 0x47, 0x48, 0x9b, 0x48, 0xaf, 0x48, 0xd7, 0x48, + 0x4c, 0x49, 0xa0, 0x49, 0xbe, 0x49, 0xd4, 0x49, 0xfa, 0x49, 0x5e, 0x4a, + 0xcc, 0x4a, 0x14, 0x4b, 0xfe, 0x4a, 0x22, 0x4b, 0x10, 0x4c, 0x0c, 0x4d, + 0xb2, 0x4d, 0x4c, 0x4e, 0x3e, 0x4e, 0x77, 0x4d, 0x98, 0x4c, 0xf6, 0x4b, + 0x67, 0x4b, 0xf0, 0x4a, 0x2a, 0x4a, 0xea, 0x48, 0x06, 0x48, 0x47, 0x47, + 0xb2, 0x46, 0xda, 0x45, 0xad, 0x44, 0x5c, 0x43, 0x43, 0x42, 0x9e, 0x41, + 0x0a, 0x41, 0x49, 0x40, 0xa6, 0x3f, 0x9d, 0x3e, 0x3c, 0x3d, 0xc6, 0x3b, + 0xf6, 0x39, 0x87, 0x37, 0xf6, 0x34, 0x87, 0x32, 0x2b, 0x30, 0x6f, 0x2d, + 0xfa, 0x2a, 0x3d, 0x29, 0x48, 0x27, 0xc2, 0x24, 0x49, 0x22, 0xca, 0x1f, + 0xa0, 0x1c, 0x7c, 0x19, 0x06, 0x17, 0xbf, 0x14, 0x9f, 0x12, 0x96, 0x10, + 0xf9, 0x0d, 0x3e, 0x0b, 0xe8, 0x08, 0x5c, 0x06, 0xe7, 0x02, 0x6e, 0xff, + 0xca, 0xfc, 0x5b, 0xfa, 0xa0, 0xf7, 0xe9, 0xf4, 0x9c, 0xf2, 0x66, 0xf0, + 0xaf, 0xed, 0xfd, 0xea, 0xcc, 0xe8, 0x6e, 0xe6, 0x82, 0xe3, 0x97, 0xe0, + 0xed, 0xdd, 0x62, 0xdb, 0x7b, 0xd8, 0xd3, 0xd5, 0x5f, 0xd3, 0x1a, 0xd1, + 0x44, 0xcf, 0xeb, 0xcd, 0x89, 0xcc, 0xca, 0xca, 0x4d, 0xc9, 0x35, 0xc8, + 0x53, 0xc7, 0x0c, 0xc6, 0x06, 0xc4, 0xca, 0xc1, 0x09, 0xc0, 0x9c, 0xbe, + 0xa8, 0xbd, 0xfd, 0xbc, 0xf2, 0xbb, 0x9b, 0xba, 0x20, 0xb9, 0xe4, 0xb7, + 0xc1, 0xb6, 0xcd, 0xb5, 0x12, 0xb5, 0x55, 0xb4, 0xd1, 0xb3, 0x86, 0xb3, + 0x19, 0xb3, 0xe8, 0xb2, 0xd7, 0xb2, 0x72, 0xb2, 0x27, 0xb2, 0xb7, 0xb1, + 0x67, 0xb1, 0x65, 0xb1, 0xae, 0xb1, 0x6b, 0xb1, 0xf2, 0xb0, 0xeb, 0xb0, + 0x0f, 0xb1, 0xfe, 0xb0, 0xeb, 0xb0, 0xcf, 0xb0, 0x94, 0xb0, 0x3e, 0xb0, + 0x29, 0xb0, 0x56, 0xb0, 0x0c, 0xb0, 0xb7, 0xaf, 0xfb, 0xaf, 0x37, 0xb0, + 0x96, 0xb0, 0x42, 0xb1, 0xe8, 0xb1, 0xb5, 0xb2, 0xc5, 0xb3, 0x93, 0xb4, + 0x93, 0xb4, 0xee, 0xb4, 0x59, 0xb6, 0xca, 0xb7, 0x87, 0xb8, 0x6f, 0xb8, + 0x33, 0xb8, 0xaf, 0xb8, 0x4a, 0xb9, 0x9d, 0xb9, 0xf2, 0xb9, 0x48, 0xba, + 0xd0, 0xba, 0xe5, 0xbb, 0x4e, 0xbd, 0xaf, 0xbe, 0xe9, 0xbf, 0xba, 0xc1, + 0xc2, 0xc3, 0x73, 0xc5, 0xa6, 0xc6, 0x6a, 0xc7, 0x83, 0xc8, 0x42, 0xca, + 0xc8, 0xcb, 0x34, 0xcd, 0x94, 0xce, 0xcc, 0xcf, 0x31, 0xd1, 0x27, 0xd3, + 0x8c, 0xd5, 0x61, 0xd7, 0x78, 0xd9, 0x3b, 0xdc, 0x40, 0xdf, 0xdd, 0xe1, + 0x0c, 0xe4, 0xe4, 0xe5, 0xd0, 0xe7, 0x65, 0xea, 0xc9, 0xec, 0xd7, 0xee, + 0xfc, 0xf0, 0x7c, 0xf3, 0xf6, 0xf5, 0x09, 0xf8, 0xde, 0xf9, 0xca, 0xfb, + 0xac, 0xfd, 0xc3, 0xff, 0x33, 0x02, 0xb1, 0x04, 0x24, 0x07, 0x57, 0x09, + 0x5f, 0x0b, 0xe6, 0x0d, 0xd1, 0x10, 0x6d, 0x13, 0x8f, 0x15, 0xfb, 0x17, + 0x43, 0x1a, 0x8e, 0x1c, 0x1a, 0x1f, 0x69, 0x21, 0x80, 0x23, 0x74, 0x25, + 0x62, 0x27, 0x07, 0x29, 0xa1, 0x2a, 0xa5, 0x2c, 0xdf, 0x2e, 0x57, 0x31, + 0xff, 0x33, 0xd1, 0x36, 0x6e, 0x39, 0x8a, 0x3b, 0x58, 0x3d, 0x32, 0x3f, + 0xc8, 0x40, 0x1b, 0x42, 0x22, 0x43, 0x1a, 0x44, 0x25, 0x45, 0xe5, 0x45, + 0x43, 0x46, 0x9b, 0x46, 0x6a, 0x47, 0x6f, 0x48, 0x69, 0x49, 0x6f, 0x4a, + 0xc7, 0x4b, 0x0e, 0x4d, 0x03, 0x4e, 0x78, 0x4e, 0xdf, 0x4e, 0x0b, 0x4f, + 0xea, 0x4e, 0xcb, 0x4e, 0x1b, 0x4f, 0x6e, 0x4f, 0xc3, 0x4f, 0xdc, 0x4f, + 0xcb, 0x4f, 0xd2, 0x4f, 0x16, 0x50, 0x24, 0x50, 0xf2, 0x4f, 0x00, 0x50, + 0x37, 0x50, 0x4e, 0x50, 0x5e, 0x50, 0x7c, 0x50, 0xab, 0x50, 0x69, 0x50, + 0xad, 0x4f, 0xa3, 0x4e, 0xe6, 0x4d, 0x42, 0x4d, 0xdc, 0x4c, 0x7c, 0x4c, + 0xbe, 0x4b, 0x08, 0x4b, 0x7b, 0x4a, 0xe4, 0x49, 0x14, 0x49, 0x07, 0x48, + 0x98, 0x46, 0x2f, 0x45, 0x16, 0x44, 0x23, 0x43, 0x55, 0x42, 0xac, 0x41, + 0x06, 0x41, 0x4b, 0x40, 0x8f, 0x3f, 0xde, 0x3e, 0xe1, 0x3d, 0x75, 0x3c, + 0xc0, 0x3a, 0xe4, 0x38, 0x83, 0x37, 0x9a, 0x36, 0xe5, 0x35, 0xc0, 0x34, + 0xf9, 0x32, 0xe1, 0x30, 0xfa, 0x2e, 0xd4, 0x2c, 0x4d, 0x2a, 0xed, 0x27, + 0xb9, 0x25, 0xb2, 0x23, 0x7d, 0x21, 0xfd, 0x1e, 0x89, 0x1c, 0x38, 0x1a, + 0xe2, 0x17, 0x67, 0x15, 0xf3, 0x12, 0xb3, 0x10, 0x9e, 0x0e, 0x79, 0x0c, + 0xea, 0x09, 0x54, 0x07, 0x26, 0x05, 0x0a, 0x03, 0xd7, 0x00, 0x98, 0xfe, + 0x41, 0xfc, 0x8d, 0xf9, 0x3c, 0xf7, 0x4f, 0xf5, 0x73, 0xf3, 0x7b, 0xf1, + 0x68, 0xef, 0x6f, 0xed, 0x7a, 0xeb, 0x87, 0xe9, 0x48, 0xe7, 0xc6, 0xe4, + 0x65, 0xe2, 0xf6, 0xdf, 0x86, 0xdd, 0x9f, 0xdb, 0x1b, 0xda, 0xa6, 0xd8, + 0xce, 0xd6, 0xe4, 0xd4, 0xe3, 0xd2, 0x84, 0xd0, 0xec, 0xcd, 0x08, 0xcc, + 0x89, 0xca, 0x1b, 0xc9, 0xe2, 0xc7, 0x9d, 0xc6, 0xe5, 0xc4, 0x79, 0xc3, + 0x6d, 0xc2, 0xe3, 0xc0, 0x3c, 0xbf, 0xd3, 0xbd, 0x41, 0xbc, 0xd2, 0xba, + 0x6a, 0xb9, 0xa1, 0xb7, 0xa9, 0xb5, 0x47, 0xb4, 0x91, 0xb3, 0xd5, 0xb2, + 0xb7, 0xb1, 0x51, 0xb0, 0x14, 0xaf, 0xf5, 0xad, 0x95, 0xac, 0x34, 0xab, + 0x05, 0xaa, 0xe1, 0xa8, 0xb3, 0xa7, 0xd9, 0xa6, 0x25, 0xa6, 0x6e, 0xa5, + 0x2b, 0xa5, 0x7b, 0xa5, 0x9a, 0xa5, 0x88, 0xa5, 0xc3, 0xa5, 0xe7, 0xa5, + 0xaf, 0xa5, 0x8b, 0xa5, 0x80, 0xa5, 0x65, 0xa5, 0x8c, 0xa5, 0x7e, 0xa5, + 0x22, 0xa5, 0x40, 0xa5, 0xed, 0xa5, 0x27, 0xa6, 0x2b, 0xa6, 0x1c, 0xa6, + 0xe5, 0xa5, 0x7b, 0xa5, 0x45, 0xa5, 0x37, 0xa5, 0x04, 0xa5, 0x91, 0xa4, + 0x8d, 0xa4, 0x2d, 0xa5, 0x9f, 0xa5, 0xf6, 0xa5, 0x7e, 0xa6, 0x34, 0xa7, + 0x14, 0xa8, 0x7e, 0xa8, 0x87, 0xa8, 0xc4, 0xa8, 0x51, 0xa9, 0xec, 0xa9, + 0x74, 0xaa, 0xf7, 0xaa, 0x40, 0xab, 0xd9, 0xab, 0xca, 0xac, 0x6b, 0xad, + 0xb3, 0xad, 0x08, 0xae, 0x10, 0xaf, 0x2c, 0xb0, 0xcb, 0xb0, 0x23, 0xb1, + 0xac, 0xb1, 0x0e, 0xb2, 0x42, 0xb2, 0xd7, 0xb2, 0xef, 0xb3, 0x21, 0xb5, + 0x30, 0xb6, 0xe9, 0xb6, 0x54, 0xb7, 0xf0, 0xb7, 0x9e, 0xb8, 0x2e, 0xb9, + 0x03, 0xba, 0x55, 0xbb, 0xdf, 0xbc, 0x5f, 0xbe, 0xb8, 0xbf, 0x01, 0xc1, + 0x83, 0xc2, 0x0c, 0xc4, 0x65, 0xc5, 0x7e, 0xc6, 0x86, 0xc7, 0xba, 0xc8, + 0x11, 0xca, 0x66, 0xcb, 0x28, 0xcd, 0x4d, 0xcf, 0x60, 0xd1, 0x69, 0xd3, + 0x7b, 0xd5, 0x5f, 0xd7, 0xe3, 0xd8, 0xca, 0xda, 0xda, 0xdc, 0xda, 0xde, + 0xab, 0xe0, 0x59, 0xe2, 0x3b, 0xe4, 0x21, 0xe6, 0xfc, 0xe7, 0xcb, 0xe9, + 0xbe, 0xeb, 0x9c, 0xed, 0x47, 0xef, 0x0b, 0xf1, 0xd3, 0xf2, 0xbc, 0xf4, + 0x9c, 0xf6, 0x67, 0xf8, 0x2a, 0xfa, 0xc1, 0xfb, 0x7f, 0xfd, 0x41, 0xff, + 0x12, 0x01, 0xd2, 0x02, 0xfc, 0x04, 0xe8, 0x06, 0x9a, 0x08, 0x59, 0x0a, + 0x48, 0x0c, 0x36, 0x0e, 0x37, 0x10, 0x36, 0x12, 0x59, 0x14, 0x62, 0x16, + 0x86, 0x18, 0xb9, 0x1a, 0xc2, 0x1c, 0xcd, 0x1e, 0xf1, 0x20, 0x27, 0x23, + 0x7a, 0x25, 0xf9, 0x27, 0x2a, 0x2a, 0x1f, 0x2c, 0xf8, 0x2d, 0xa3, 0x2f, + 0x23, 0x31, 0xf4, 0x32, 0x2c, 0x35, 0x40, 0x37, 0x23, 0x39, 0xfe, 0x3a, + 0x11, 0x3d, 0x2c, 0x3f, 0xe8, 0x40, 0x8c, 0x42, 0x55, 0x44, 0x37, 0x46, + 0x99, 0x47, 0xcb, 0x48, 0x12, 0x4a, 0x60, 0x4b, 0x86, 0x4c, 0x9b, 0x4d, + 0xc8, 0x4e, 0xec, 0x4f, 0xe3, 0x50, 0x8a, 0x51, 0x23, 0x52, 0xd8, 0x52, + 0x68, 0x53, 0x9b, 0x53, 0xb1, 0x53, 0x11, 0x54, 0x94, 0x54, 0xf7, 0x54, + 0x4f, 0x55, 0xa4, 0x55, 0x03, 0x56, 0x51, 0x56, 0x92, 0x56, 0xfa, 0x56, + 0x59, 0x57, 0xad, 0x57, 0xcd, 0x57, 0xc5, 0x57, 0xa8, 0x57, 0x64, 0x57, + 0x49, 0x57, 0x63, 0x57, 0x64, 0x57, 0x40, 0x57, 0xf6, 0x56, 0xfc, 0x56, + 0x36, 0x57, 0x3b, 0x57, 0x1e, 0x57, 0x1c, 0x57, 0x03, 0x57, 0xee, 0x56, + 0xa5, 0x56, 0x80, 0x56, 0xd4, 0x56, 0xe4, 0x56, 0x92, 0x56, 0xf0, 0x55, + 0x02, 0x55, 0xab, 0x53, 0xb5, 0x52, 0x51, 0x52, 0x08, 0x52, 0x80, 0x51, + 0xb4, 0x50, 0xde, 0x4f, 0x27, 0x4f, 0x63, 0x4e, 0x58, 0x4d, 0x72, 0x4c, + 0x82, 0x4b, 0x81, 0x4a, 0x87, 0x49, 0xb4, 0x48, 0xb1, 0x47, 0x99, 0x46, + 0xb4, 0x45, 0x34, 0x45, 0xb8, 0x44, 0x2f, 0x44, 0x7f, 0x43, 0xa0, 0x42, + 0xcb, 0x41, 0xd1, 0x40, 0xeb, 0x3f, 0x28, 0x3f, 0x3d, 0x3e, 0x09, 0x3d, + 0x9d, 0x3b, 0x40, 0x3a, 0x1c, 0x39, 0xeb, 0x37, 0xd1, 0x36, 0xb3, 0x35, + 0x8b, 0x34, 0x0b, 0x33, 0x51, 0x31, 0xfb, 0x2f, 0xb9, 0x2e, 0x54, 0x2d, + 0xaf, 0x2b, 0xdf, 0x29, 0xf1, 0x27, 0x3a, 0x26, 0x6f, 0x24, 0x56, 0x22, + 0x20, 0x20, 0x0a, 0x1e, 0x3b, 0x1c, 0x55, 0x1a, 0x6c, 0x18, 0xaa, 0x16, + 0xef, 0x14, 0x0a, 0x13, 0x17, 0x11, 0x1c, 0x0f, 0x22, 0x0d, 0x46, 0x0b, + 0x53, 0x09, 0x46, 0x07, 0x46, 0x05, 0x4d, 0x03, 0x1a, 0x01, 0xd3, 0xfe, + 0x94, 0xfc, 0x8c, 0xfa, 0x8f, 0xf8, 0xc1, 0xf6, 0x27, 0xf5, 0x8f, 0xf3, + 0xf2, 0xf1, 0x74, 0xf0, 0xfa, 0xee, 0x4d, 0xed, 0x9e, 0xeb, 0xa2, 0xe9, + 0x73, 0xe7, 0xa9, 0xe5, 0x2d, 0xe4, 0xa3, 0xe2, 0xf9, 0xe0, 0x50, 0xdf, + 0xb9, 0xdd, 0x34, 0xdc, 0xad, 0xda, 0x0b, 0xd9, 0x77, 0xd7, 0xb9, 0xd5, + 0x37, 0xd4, 0xff, 0xd2, 0x8a, 0xd1, 0x14, 0xd0, 0xba, 0xce, 0x7d, 0xcd, + 0x2c, 0xcc, 0xa1, 0xca, 0x22, 0xc9, 0xa9, 0xc7, 0x0e, 0xc6, 0x66, 0xc4, + 0xfc, 0xc2, 0xa5, 0xc1, 0x4a, 0xc0, 0xff, 0xbe, 0xf7, 0xbd, 0x0e, 0xbd, + 0x1d, 0xbc, 0x16, 0xbb, 0xad, 0xb9, 0x44, 0xb8, 0xd7, 0xb6, 0x9e, 0xb5, + 0x9f, 0xb4, 0x97, 0xb3, 0x72, 0xb2, 0x5f, 0xb1, 0x67, 0xb0, 0x89, 0xaf, + 0x9d, 0xae, 0xbe, 0xad, 0x08, 0xad, 0x5d, 0xac, 0x8b, 0xab, 0xad, 0xaa, + 0xe4, 0xa9, 0x59, 0xa9, 0xc4, 0xa8, 0x02, 0xa8, 0x4d, 0xa7, 0xc2, 0xa6, + 0x4a, 0xa6, 0x09, 0xa6, 0xd2, 0xa5, 0x50, 0xa5, 0xec, 0xa4, 0xc2, 0xa4, + 0xd9, 0xa4, 0xbd, 0xa4, 0x97, 0xa4, 0xa5, 0xa4, 0xbf, 0xa4, 0xb4, 0xa4, + 0x8f, 0xa4, 0x31, 0xa4, 0x39, 0xa4, 0x7d, 0xa4, 0xab, 0xa4, 0xc7, 0xa4, + 0xb3, 0xa4, 0xab, 0xa4, 0xca, 0xa4, 0x05, 0xa5, 0x1e, 0xa5, 0x2a, 0xa5, + 0x2c, 0xa5, 0x18, 0xa5, 0x01, 0xa5, 0x33, 0xa5, 0x8c, 0xa5, 0xb2, 0xa5, + 0x81, 0xa5, 0x5c, 0xa5, 0x6e, 0xa5, 0x79, 0xa5, 0x4e, 0xa5, 0x17, 0xa5, + 0xff, 0xa4, 0x1c, 0xa5, 0x45, 0xa5, 0x8a, 0xa5, 0xbf, 0xa5, 0xdb, 0xa5, + 0x41, 0xa6, 0xfb, 0xa6, 0xc6, 0xa7, 0x86, 0xa8, 0x29, 0xa9, 0x97, 0xa9, + 0x27, 0xaa, 0xd7, 0xaa, 0x6d, 0xab, 0xf4, 0xab, 0x34, 0xac, 0x69, 0xac, + 0xc6, 0xac, 0x37, 0xad, 0xaa, 0xad, 0x34, 0xae, 0xd3, 0xae, 0x81, 0xaf, + 0x16, 0xb0, 0x72, 0xb0, 0xc8, 0xb0, 0x36, 0xb1, 0x91, 0xb1, 0xe0, 0xb1, + 0x3b, 0xb2, 0x8e, 0xb2, 0xe0, 0xb2, 0x2a, 0xb3, 0xab, 0xb3, 0x3a, 0xb4, + 0xf1, 0xb4, 0xc0, 0xb5, 0xae, 0xb6, 0x91, 0xb7, 0x82, 0xb8, 0x98, 0xb9, + 0x8f, 0xba, 0x88, 0xbb, 0x65, 0xbc, 0x20, 0xbd, 0xcb, 0xbd, 0xaf, 0xbe, + 0x94, 0xbf, 0x84, 0xc0, 0x85, 0xc1, 0x7b, 0xc2, 0x67, 0xc3, 0x66, 0xc4, + 0x7f, 0xc5, 0x89, 0xc6, 0x6b, 0xc7, 0x38, 0xc8, 0x29, 0xc9, 0x4a, 0xca, + 0x82, 0xcb, 0xc1, 0xcc, 0x12, 0xce, 0x5e, 0xcf, 0xb0, 0xd0, 0x25, 0xd2, + 0x66, 0xd3, 0xde, 0xd4, 0x6c, 0xd6, 0x28, 0xd8, 0xd7, 0xd9, 0x80, 0xdb, + 0xf7, 0xdc, 0x6f, 0xde, 0xd0, 0xdf, 0x22, 0xe1, 0x7a, 0xe2, 0xe5, 0xe3, + 0x7a, 0xe5, 0xea, 0xe6, 0x51, 0xe8, 0xeb, 0xe9, 0x70, 0xeb, 0xb3, 0xec, + 0x01, 0xee, 0x60, 0xef, 0xcb, 0xf0, 0x1d, 0xf2, 0x7b, 0xf3, 0xcf, 0xf4, + 0x39, 0xf6, 0xc8, 0xf7, 0x82, 0xf9, 0x4a, 0xfb, 0xf2, 0xfc, 0x8c, 0xfe, + 0x01, 0x00, 0x68, 0x01, 0x15, 0x03, 0xe6, 0x04, 0xbc, 0x06, 0x42, 0x08, + 0xbb, 0x09, 0x2b, 0x0b, 0xc7, 0x0c, 0x35, 0x0e, 0x94, 0x0f, 0xf2, 0x10, + 0x59, 0x12, 0xbc, 0x13, 0x34, 0x15, 0xac, 0x16, 0x1c, 0x18, 0x79, 0x19, + 0xdc, 0x1a, 0x6d, 0x1c, 0x21, 0x1e, 0xca, 0x1f, 0x70, 0x21, 0x02, 0x23, + 0x6c, 0x24, 0x9e, 0x25, 0x45, 0x27, 0x02, 0x29, 0x95, 0x2a, 0xff, 0x2b, + 0x72, 0x2d, 0xe8, 0x2e, 0x48, 0x30, 0x7c, 0x31, 0xd2, 0x32, 0x3d, 0x34, + 0xac, 0x35, 0x26, 0x37, 0xbc, 0x38, 0x4c, 0x3a, 0x90, 0x3b, 0xef, 0x3c, + 0x61, 0x3e, 0xe8, 0x3f, 0x59, 0x41, 0xab, 0x42, 0xf7, 0x43, 0x2d, 0x45, + 0x6c, 0x46, 0x78, 0x47, 0xb4, 0x48, 0x2e, 0x4a, 0x8e, 0x4b, 0xd7, 0x4c, + 0xf4, 0x4d, 0xee, 0x4e, 0xcb, 0x4f, 0xc3, 0x50, 0xc2, 0x51, 0xac, 0x52, + 0x61, 0x53, 0xf3, 0x53, 0xac, 0x54, 0x5f, 0x55, 0xf4, 0x55, 0x7f, 0x56, + 0x04, 0x57, 0x9c, 0x57, 0x1f, 0x58, 0x7c, 0x58, 0xbc, 0x58, 0x0b, 0x59, + 0x71, 0x59, 0xc1, 0x59, 0x0b, 0x5a, 0x3e, 0x5a, 0x8b, 0x5a, 0xac, 0x5a, + 0xa9, 0x5a, 0x8a, 0x5a, 0x6c, 0x5a, 0x4c, 0x5a, 0x39, 0x5a, 0x32, 0x5a, + 0x40, 0x5a, 0x33, 0x5a, 0x44, 0x5a, 0x58, 0x5a, 0x79, 0x5a, 0x7a, 0x5a, + 0x69, 0x5a, 0x49, 0x5a, 0x54, 0x5a, 0x78, 0x5a, 0x72, 0x5a, 0x5f, 0x5a, + 0x31, 0x5a, 0x11, 0x5a, 0xf9, 0x59, 0xea, 0x59, 0xd1, 0x59, 0xa1, 0x59, + 0x48, 0x59, 0xf0, 0x58, 0xa2, 0x58, 0x6e, 0x58, 0x60, 0x58, 0x46, 0x58, + 0x3f, 0x58, 0x47, 0x58, 0x40, 0x58, 0x08, 0x58, 0x9c, 0x57, 0x11, 0x57, + 0x83, 0x56, 0xd7, 0x55, 0x42, 0x55, 0xab, 0x54, 0x06, 0x54, 0x63, 0x53, + 0xa6, 0x52, 0xf0, 0x51, 0x55, 0x51, 0xbc, 0x50, 0x1e, 0x50, 0x8e, 0x4f, + 0xf3, 0x4e, 0x34, 0x4e, 0x6b, 0x4d, 0xc9, 0x4c, 0x30, 0x4c, 0x7d, 0x4b, + 0xd8, 0x4a, 0x49, 0x4a, 0xad, 0x49, 0x11, 0x49, 0x6c, 0x48, 0xa4, 0x47, + 0xec, 0x46, 0x6c, 0x46, 0xde, 0x45, 0x5d, 0x45, 0xbc, 0x44, 0xf1, 0x43, + 0x34, 0x43, 0x8c, 0x42, 0xf8, 0x41, 0x47, 0x41, 0x6a, 0x40, 0x72, 0x3f, + 0x8b, 0x3e, 0xb3, 0x3d, 0xf2, 0x3c, 0x2f, 0x3c, 0x5c, 0x3b, 0x96, 0x3a, + 0xbc, 0x39, 0xb2, 0x38, 0x91, 0x37, 0x8c, 0x36, 0x75, 0x35, 0x63, 0x34, + 0x5e, 0x33, 0x63, 0x32, 0x4b, 0x31, 0x3c, 0x30, 0x1e, 0x2f, 0x07, 0x2e, + 0xd0, 0x2c, 0xb2, 0x2b, 0x84, 0x2a, 0x4d, 0x29, 0xfc, 0x27, 0xa5, 0x26, + 0x2f, 0x25, 0x95, 0x23, 0x1f, 0x22, 0xad, 0x20, 0x3a, 0x1f, 0x9e, 0x1d, + 0x10, 0x1c, 0x6e, 0x1a, 0xe3, 0x18, 0x56, 0x17, 0xdb, 0x15, 0x58, 0x14, + 0xba, 0x12, 0x2a, 0x11, 0x8b, 0x0f, 0xf4, 0x0d, 0x5b, 0x0c, 0xd3, 0x0a, + 0x5f, 0x09, 0xe5, 0x07, 0x4a, 0x06, 0xc0, 0x04, 0x3e, 0x03, 0xb6, 0x01, + 0x37, 0x00, 0xca, 0xfe, 0x74, 0xfd, 0x00, 0xfc, 0xa5, 0xfa, 0x4a, 0xf9, + 0xd1, 0xf7, 0x7e, 0xf6, 0x1c, 0xf5, 0x9d, 0xf3, 0x4f, 0xf2, 0x0e, 0xf1, + 0xc0, 0xef, 0x3a, 0xee, 0xd8, 0xec, 0x69, 0xeb, 0x0c, 0xea, 0xad, 0xe8, + 0x56, 0xe7, 0xf8, 0xe5, 0xbe, 0xe4, 0x98, 0xe3, 0x61, 0xe2, 0x03, 0xe1, + 0x99, 0xdf, 0x4d, 0xde, 0x0e, 0xdd, 0xde, 0xdb, 0xad, 0xda, 0x84, 0xd9, + 0x62, 0xd8, 0x32, 0xd7, 0x01, 0xd6, 0xb7, 0xd4, 0x87, 0xd3, 0x97, 0xd2, + 0x89, 0xd1, 0x89, 0xd0, 0x6e, 0xcf, 0x65, 0xce, 0x5d, 0xcd, 0x44, 0xcc, + 0x13, 0xcb, 0xf2, 0xc9, 0xd3, 0xc8, 0xad, 0xc7, 0x9b, 0xc6, 0x94, 0xc5, + 0x8e, 0xc4, 0x7b, 0xc3, 0x92, 0xc2, 0xad, 0xc1, 0xb2, 0xc0, 0xb9, 0xbf, + 0xb3, 0xbe, 0xc0, 0xbd, 0xd5, 0xbc, 0xf2, 0xbb, 0xe1, 0xba, 0xc7, 0xb9, + 0xc7, 0xb8, 0xe8, 0xb7, 0x09, 0xb7, 0x2c, 0xb6, 0x66, 0xb5, 0xb1, 0xb4, + 0xf6, 0xb3, 0x32, 0xb3, 0x53, 0xb2, 0x92, 0xb1, 0xdb, 0xb0, 0x0d, 0xb0, + 0x46, 0xaf, 0x62, 0xae, 0x98, 0xad, 0xd1, 0xac, 0x3f, 0xac, 0xb0, 0xab, + 0x34, 0xab, 0xb1, 0xaa, 0x45, 0xaa, 0xda, 0xa9, 0x6a, 0xa9, 0xf1, 0xa8, + 0x7d, 0xa8, 0x04, 0xa8, 0xbb, 0xa7, 0x80, 0xa7, 0x41, 0xa7, 0x02, 0xa7, + 0xb6, 0xa6, 0x68, 0xa6, 0x3b, 0xa6, 0x1c, 0xa6, 0x0d, 0xa6, 0xfc, 0xa5, + 0xd4, 0xa5, 0xa6, 0xa5, 0x81, 0xa5, 0x76, 0xa5, 0x61, 0xa5, 0x54, 0xa5, + 0x48, 0xa5, 0x47, 0xa5, 0x4b, 0xa5, 0x49, 0xa5, 0x38, 0xa5, 0x4b, 0xa5, + 0x6c, 0xa5, 0xa3, 0xa5, 0xda, 0xa5, 0xfe, 0xa5, 0x21, 0xa6, 0x4a, 0xa6, + 0x8a, 0xa6, 0xb4, 0xa6, 0xe0, 0xa6, 0xf3, 0xa6, 0x1b, 0xa7, 0x17, 0xa7, + 0x40, 0xa7, 0x8e, 0xa7, 0xcd, 0xa7, 0x06, 0xa8, 0x3e, 0xa8, 0x86, 0xa8, + 0xbd, 0xa8, 0xde, 0xa8, 0xf6, 0xa8, 0x1c, 0xa9, 0x49, 0xa9, 0x5c, 0xa9, + 0x79, 0xa9, 0x93, 0xa9, 0xab, 0xa9, 0xe6, 0xa9, 0x2c, 0xaa, 0x82, 0xaa, + 0xbc, 0xaa, 0xec, 0xaa, 0x32, 0xab, 0x69, 0xab, 0xa7, 0xab, 0xde, 0xab, + 0x19, 0xac, 0x53, 0xac, 0xbb, 0xac, 0x14, 0xad, 0x8a, 0xad, 0xeb, 0xad, + 0x6c, 0xae, 0xe1, 0xae, 0x62, 0xaf, 0xd9, 0xaf, 0x58, 0xb0, 0xc0, 0xb0, + 0x36, 0xb1, 0x99, 0xb1, 0x11, 0xb2, 0x71, 0xb2, 0xdc, 0xb2, 0x58, 0xb3, + 0xbb, 0xb3, 0x37, 0xb4, 0xb6, 0xb4, 0x46, 0xb5, 0xca, 0xb5, 0x50, 0xb6, + 0xd9, 0xb6, 0x6c, 0xb7, 0x03, 0xb8, 0x7e, 0xb8, 0xf0, 0xb8, 0x64, 0xb9, + 0xcf, 0xb9, 0x47, 0xba, 0xd3, 0xba, 0x60, 0xbb, 0xe8, 0xbb, 0x70, 0xbc, + 0xf3, 0xbc, 0x82, 0xbd, 0x05, 0xbe, 0xa1, 0xbe, 0x2a, 0xbf, 0xae, 0xbf, + 0x25, 0xc0, 0xac, 0xc0, 0x52, 0xc1, 0xde, 0xc1, 0x75, 0xc2, 0x11, 0xc3, + 0xb5, 0xc3, 0x42, 0xc4, 0xc5, 0xc4, 0x6d, 0xc5, 0x0b, 0xc6, 0xb2, 0xc6, + 0x4b, 0xc7, 0xf6, 0xc7, 0x9b, 0xc8, 0x4f, 0xc9, 0x17, 0xca, 0xf3, 0xca, + 0xc6, 0xcb, 0x9a, 0xcc, 0x7b, 0xcd, 0x54, 0xce, 0x32, 0xcf, 0x09, 0xd0, + 0xd7, 0xd0, 0xc9, 0xd1, 0xc1, 0xd2, 0xb8, 0xd3, 0xb6, 0xd4, 0xae, 0xd5, + 0xbc, 0xd6, 0xca, 0xd7, 0xd2, 0xd8, 0xca, 0xd9, 0xbd, 0xda, 0xc8, 0xdb, + 0xd8, 0xdc, 0xf9, 0xdd, 0x08, 0xdf, 0x1e, 0xe0, 0x39, 0xe1, 0x4e, 0xe2, + 0x60, 0xe3, 0x7a, 0xe4, 0x96, 0xe5, 0xc1, 0xe6, 0xde, 0xe7, 0x0e, 0xe9, + 0x2a, 0xea, 0x42, 0xeb, 0x7a, 0xec, 0x9f, 0xed, 0xbb, 0xee, 0xd6, 0xef, + 0xef, 0xf0, 0x0e, 0xf2, 0x30, 0xf3, 0x55, 0xf4, 0x68, 0xf5, 0x7e, 0xf6, + 0xa4, 0xf7, 0xc0, 0xf8, 0xea, 0xf9, 0x10, 0xfb, 0x41, 0xfc, 0x7d, 0xfd, + 0xad, 0xfe, 0xe3, 0xff, 0x10, 0x01, 0x27, 0x02, 0x58, 0x03, 0x74, 0x04, + 0xa4, 0x05, 0xd5, 0x06, 0x0b, 0x08, 0x36, 0x09, 0x5c, 0x0a, 0x76, 0x0b, + 0x9a, 0x0c, 0xc1, 0x0d, 0xd8, 0x0e, 0xf5, 0x0f, 0x15, 0x11, 0x3f, 0x12, + 0x70, 0x13, 0x8e, 0x14, 0xcc, 0x15, 0xf2, 0x16, 0x31, 0x18, 0x4b, 0x19, + 0x82, 0x1a, 0xa1, 0x1b, 0xbc, 0x1c, 0xde, 0x1d, 0xe9, 0x1e, 0x13, 0x20, + 0x33, 0x21, 0x6c, 0x22, 0x80, 0x23, 0xa7, 0x24, 0xbc, 0x25, 0xde, 0x26, + 0xe7, 0x27, 0x07, 0x29, 0x28, 0x2a, 0x36, 0x2b, 0x4d, 0x2c, 0x71, 0x2d, + 0x91, 0x2e, 0xbe, 0x2f, 0xd6, 0x30, 0xfb, 0x31, 0x20, 0x33, 0x46, 0x34, + 0x59, 0x35, 0x7a, 0x36, 0xa1, 0x37, 0xc2, 0x38, 0xdf, 0x39, 0x01, 0x3b, + 0x0f, 0x3c, 0x27, 0x3d, 0x1f, 0x3e, 0x2e, 0x3f, 0x43, 0x40, 0x5b, 0x41, + 0x73, 0x42, 0x8e, 0x43, 0xaf, 0x44, 0xbc, 0x45, 0xcc, 0x46, 0xd8, 0x47, + 0xec, 0x48, 0xe1, 0x49, 0xd1, 0x4a, 0xc4, 0x4b, 0xb6, 0x4c, 0xa9, 0x4d, + 0x9d, 0x4e, 0x88, 0x4f, 0x75, 0x50, 0x4c, 0x51, 0x3b, 0x52, 0x05, 0x53, + 0xd9, 0x53, 0xa1, 0x54, 0x6f, 0x55, 0x33, 0x56, 0xe5, 0x56, 0x7d, 0x57, + 0x15, 0x58, 0xb3, 0x58, 0x4e, 0x59, 0xdb, 0x59, 0x55, 0x5a, 0xc8, 0x5a, + 0x36, 0x5b, 0xa9, 0x5b, 0x09, 0x5c, 0x5a, 0x5c, 0xab, 0x5c, 0xf1, 0x5c, + 0x34, 0x5d, 0x6a, 0x5d, 0x9e, 0x5d, 0xc1, 0x5d, 0xea, 0x5d, 0x0b, 0x5e, + 0x28, 0x5e, 0x3d, 0x5e, 0x41, 0x5e, 0x51, 0x5e, 0x5f, 0x5e, 0x69, 0x5e, + 0x79, 0x5e, 0x6a, 0x5e, 0x78, 0x5e, 0x76, 0x5e, 0x7f, 0x5e, 0x72, 0x5e, + 0x70, 0x5e, 0x61, 0x5e, 0x61, 0x5e, 0x42, 0x5e, 0x36, 0x5e, 0x2f, 0x5e, + 0x2c, 0x5e, 0x1a, 0x5e, 0xec, 0x5d, 0xbf, 0x5d, 0x94, 0x5d, 0x71, 0x5d, + 0x4c, 0x5d, 0x24, 0x5d, 0xfa, 0x5c, 0xc3, 0x5c, 0x8c, 0x5c, 0x59, 0x5c, + 0x3e, 0x5c, 0x0c, 0x5c, 0xd3, 0x5b, 0xb1, 0x5b, 0x78, 0x5b, 0x45, 0x5b, + 0x14, 0x5b, 0xed, 0x5a, 0xc0, 0x5a, 0x89, 0x5a, 0x4f, 0x5a, 0x16, 0x5a, + 0xe5, 0x59, 0xb5, 0x59, 0x84, 0x59, 0x4e, 0x59, 0x0d, 0x59, 0xcf, 0x58, + 0xa6, 0x58, 0x79, 0x58, 0x3e, 0x58, 0xf8, 0x57, 0xc0, 0x57, 0x83, 0x57, + 0x38, 0x57, 0x03, 0x57, 0xc1, 0x56, 0x65, 0x56, 0xe0, 0x55, 0x52, 0x55, + 0xd0, 0x54, 0x4c, 0x54, 0xbe, 0x53, 0x32, 0x53, 0xa7, 0x52, 0x2a, 0x52, + 0x95, 0x51, 0x09, 0x51, 0x76, 0x50, 0xe9, 0x4f, 0x69, 0x4f, 0xe2, 0x4e, + 0x49, 0x4e, 0xc0, 0x4d, 0x38, 0x4d, 0xbd, 0x4c, 0x2d, 0x4c, 0x98, 0x4b, + 0x07, 0x4b, 0x76, 0x4a, 0xdc, 0x49, 0x4a, 0x49, 0xb9, 0x48, 0x2d, 0x48, + 0x9c, 0x47, 0x19, 0x47, 0x80, 0x46, 0xf9, 0x45, 0x66, 0x45, 0xd6, 0x44, + 0x47, 0x44, 0xb5, 0x43, 0x14, 0x43, 0x74, 0x42, 0xd4, 0x41, 0x42, 0x41, + 0xa4, 0x40, 0x18, 0x40, 0x85, 0x3f, 0xeb, 0x3e, 0x52, 0x3e, 0xb2, 0x3d, + 0x0c, 0x3d, 0x7a, 0x3c, 0xdb, 0x3b, 0x3a, 0x3b, 0x87, 0x3a, 0xe0, 0x39, + 0x29, 0x39, 0x88, 0x38, 0xd1, 0x37, 0x16, 0x37, 0x4d, 0x36, 0x9e, 0x35, + 0xdc, 0x34, 0x19, 0x34, 0x4a, 0x33, 0x83, 0x32, 0xb7, 0x31, 0xec, 0x30, + 0x1c, 0x30, 0x47, 0x2f, 0x71, 0x2e, 0x88, 0x2d, 0xa6, 0x2c, 0xbb, 0x2b, + 0xd0, 0x2a, 0xd8, 0x29, 0xdb, 0x28, 0xe3, 0x27, 0xf5, 0x26, 0xf1, 0x25, + 0xf8, 0x24, 0xdc, 0x23, 0xdb, 0x22, 0xca, 0x21, 0xa7, 0x20, 0x85, 0x1f, + 0x5a, 0x1e, 0x30, 0x1d, 0x0a, 0x1c, 0xd5, 0x1a, 0xa6, 0x19, 0x6d, 0x18, + 0x3d, 0x17, 0xff, 0x15, 0xbf, 0x14, 0x81, 0x13, 0x57, 0x12, 0x15, 0x11, + 0xe0, 0x0f, 0xa2, 0x0e, 0x65, 0x0d, 0x27, 0x0c, 0xf1, 0x0a, 0xb2, 0x09, + 0x77, 0x08, 0x4b, 0x07, 0x0a, 0x06, 0xc9, 0x04, 0x97, 0x03, 0x65, 0x02, + 0x3b, 0x01, 0x03, 0x00, 0xd2, 0xfe, 0x95, 0xfd, 0x6f, 0xfc, 0x50, 0xfb, + 0x19, 0xfa, 0xf0, 0xf8, 0xb8, 0xf7, 0x97, 0xf6, 0x65, 0xf5, 0x48, 0xf4, + 0x24, 0xf3, 0xfe, 0xf1, 0xec, 0xf0, 0xd2, 0xef, 0xa9, 0xee, 0x95, 0xed, + 0x76, 0xec, 0x64, 0xeb, 0x61, 0xea, 0x43, 0xe9, 0x3a, 0xe8, 0x21, 0xe7, + 0x14, 0xe6, 0xff, 0xe4, 0x06, 0xe4, 0x04, 0xe3, 0x04, 0xe2, 0x01, 0xe1, + 0x02, 0xe0, 0x04, 0xdf, 0x16, 0xde, 0x1f, 0xdd, 0x29, 0xdc, 0x2d, 0xdb, + 0x3d, 0xda, 0x45, 0xd9, 0x5a, 0xd8, 0x6f, 0xd7, 0x74, 0xd6, 0x8a, 0xd5, + 0x91, 0xd4, 0xa5, 0xd3, 0xbb, 0xd2, 0xdb, 0xd1, 0x01, 0xd1, 0x17, 0xd0, + 0x42, 0xcf, 0x5e, 0xce, 0x94, 0xcd, 0xb1, 0xcc, 0xe8, 0xcb, 0x04, 0xcb, + 0x29, 0xca, 0x4e, 0xc9, 0x78, 0xc8, 0x99, 0xc7, 0xc4, 0xc6, 0xff, 0xc5, + 0x3d, 0xc5, 0x76, 0xc4, 0xa6, 0xc3, 0xe4, 0xc2, 0x17, 0xc2, 0x4e, 0xc1, + 0x8a, 0xc0, 0xc5, 0xbf, 0x0b, 0xbf, 0x42, 0xbe, 0x8e, 0xbd, 0xd8, 0xbc, + 0x20, 0xbc, 0x60, 0xbb, 0xbb, 0xba, 0x08, 0xba, 0x5a, 0xb9, 0xba, 0xb8, + 0x08, 0xb8, 0x64, 0xb7, 0xb1, 0xb6, 0x0c, 0xb6, 0x5d, 0xb5, 0xbf, 0xb4, + 0x10, 0xb4, 0x7b, 0xb3, 0xd0, 0xb2, 0x3d, 0xb2, 0xa1, 0xb1, 0x0f, 0xb1, + 0x84, 0xb0, 0xf2, 0xaf, 0x63, 0xaf, 0xd3, 0xae, 0x50, 0xae, 0xbd, 0xad, + 0x49, 0xad, 0xc1, 0xac, 0x4d, 0xac, 0xc6, 0xab, 0x56, 0xab, 0xe4, 0xaa, + 0x83, 0xaa, 0x0d, 0xaa, 0xac, 0xa9, 0x49, 0xa9, 0xf3, 0xa8, 0x9e, 0xa8, + 0x4e, 0xa8, 0x07, 0xa8, 0xc5, 0xa7, 0x8d, 0xa7, 0x56, 0xa7, 0x1d, 0xa7, + 0xf6, 0xa6, 0xc7, 0xa6, 0xad, 0xa6, 0x8c, 0xa6, 0x74, 0xa6, 0x58, 0xa6, + 0x47, 0xa6, 0x2d, 0xa6, 0x24, 0xa6, 0x23, 0xa6, 0x21, 0xa6, 0x19, 0xa6, + 0x20, 0xa6, 0x1f, 0xa6, 0x28, 0xa6, 0x3c, 0xa6, 0x4e, 0xa6, 0x59, 0xa6, + 0x6e, 0xa6, 0x84, 0xa6, 0x9a, 0xa6, 0xb7, 0xa6, 0xd4, 0xa6, 0xef, 0xa6, + 0x0a, 0xa7, 0x2f, 0xa7, 0x53, 0xa7, 0x77, 0xa7, 0x9c, 0xa7, 0xbc, 0xa7, + 0xe5, 0xa7, 0x10, 0xa8, 0x35, 0xa8, 0x6d, 0xa8, 0x9b, 0xa8, 0xcb, 0xa8, + 0xf5, 0xa8, 0x23, 0xa9, 0x5a, 0xa9, 0x80, 0xa9, 0xb7, 0xa9, 0xee, 0xa9, + 0x1c, 0xaa, 0x46, 0xaa, 0x78, 0xaa, 0xb2, 0xaa, 0xeb, 0xaa, 0x1a, 0xab, + 0x57, 0xab, 0x84, 0xab, 0xba, 0xab, 0xef, 0xab, 0x22, 0xac, 0x55, 0xac, + 0x88, 0xac, 0xc1, 0xac, 0xf5, 0xac, 0x2a, 0xad, 0x67, 0xad, 0x9f, 0xad, + 0xe0, 0xad, 0x14, 0xae, 0x4c, 0xae, 0x82, 0xae, 0xb8, 0xae, 0xf8, 0xae, + 0x2c, 0xaf, 0x6a, 0xaf, 0x9d, 0xaf, 0xd4, 0xaf, 0x05, 0xb0, 0x38, 0xb0, + 0x77, 0xb0, 0xb2, 0xb0, 0xf8, 0xb0, 0x3c, 0xb1, 0x97, 0xb1, 0x05, 0xb2, + 0x6f, 0xb2, 0xdf, 0xb2, 0x48, 0xb3, 0xb2, 0xb3, 0x16, 0xb4, 0x7b, 0xb4, + 0xe5, 0xb4, 0x54, 0xb5, 0xc3, 0xb5, 0x26, 0xb6, 0x97, 0xb6, 0x03, 0xb7, + 0x68, 0xb7, 0xce, 0xb7, 0x44, 0xb8, 0xae, 0xb8, 0x20, 0xb9, 0x87, 0xb9, + 0xf1, 0xb9, 0x5d, 0xba, 0xc6, 0xba, 0x24, 0xbb, 0xa1, 0xbb, 0x05, 0xbc, + 0x79, 0xbc, 0xdc, 0xbc, 0x4b, 0xbd, 0xba, 0xbd, 0x24, 0xbe, 0x9b, 0xbe, + 0x07, 0xbf, 0x72, 0xbf, 0xe5, 0xbf, 0x46, 0xc0, 0xc3, 0xc0, 0x1f, 0xc1, + 0x91, 0xc1, 0x01, 0xc2, 0x79, 0xc2, 0xf1, 0xc2, 0x66, 0xc3, 0xe5, 0xc3, + 0x55, 0xc4, 0xc8, 0xc4, 0x3e, 0xc5, 0xb3, 0xc5, 0x2d, 0xc6, 0xa7, 0xc6, + 0x27, 0xc7, 0x97, 0xc7, 0x1f, 0xc8, 0xa0, 0xc8, 0x29, 0xc9, 0xad, 0xc9, + 0x36, 0xca, 0xad, 0xca, 0x3d, 0xcb, 0xc0, 0xcb, 0x47, 0xcc, 0xe9, 0xcc, + 0x6f, 0xcd, 0x06, 0xce, 0x84, 0xce, 0x1a, 0xcf, 0xbb, 0xcf, 0x55, 0xd0, + 0xf6, 0xd0, 0x8b, 0xd1, 0x30, 0xd2, 0xd2, 0xd2, 0x79, 0xd3, 0x1c, 0xd4, + 0xcf, 0xd4, 0x83, 0xd5, 0x36, 0xd6, 0xe1, 0xd6, 0x96, 0xd7, 0x5f, 0xd8, + 0x1c, 0xd9, 0xe2, 0xd9, 0xa8, 0xda, 0x6c, 0xdb, 0x43, 0xdc, 0x04, 0xdd, + 0xd8, 0xdd, 0xac, 0xde, 0x8a, 0xdf, 0x5b, 0xe0, 0x39, 0xe1, 0x0b, 0xe2, + 0xf5, 0xe2, 0xde, 0xe3, 0xbc, 0xe4, 0x9e, 0xe5, 0x83, 0xe6, 0x62, 0xe7, + 0x51, 0xe8, 0x34, 0xe9, 0x1e, 0xea, 0x12, 0xeb, 0xf7, 0xeb, 0xe5, 0xec, + 0xc5, 0xed, 0xc2, 0xee, 0xb1, 0xef, 0xa6, 0xf0, 0x90, 0xf1, 0x7e, 0xf2, + 0x6f, 0xf3, 0x56, 0xf4, 0x48, 0xf5, 0x35, 0xf6, 0x29, 0xf7, 0x17, 0xf8, + 0x0a, 0xf9, 0x00, 0xfa, 0xe7, 0xfa, 0xde, 0xfb, 0xc9, 0xfc, 0xc1, 0xfd, + 0xac, 0xfe, 0xae, 0xff, 0xa2, 0x00, 0x8d, 0x01, 0x70, 0x02, 0x62, 0x03, + 0x4e, 0x04, 0x3a, 0x05, 0x26, 0x06, 0x16, 0x07, 0xff, 0x07, 0xf3, 0x08, + 0xda, 0x09, 0xbe, 0x0a, 0xb9, 0x0b, 0xa1, 0x0c, 0x9b, 0x0d, 0x7d, 0x0e, + 0x66, 0x0f, 0x54, 0x10, 0x36, 0x11, 0x20, 0x12, 0x11, 0x13, 0xf3, 0x13, + 0xea, 0x14, 0xd1, 0x15, 0xb6, 0x16, 0x9b, 0x17, 0x83, 0x18, 0x7f, 0x19, + 0x58, 0x1a, 0x53, 0x1b, 0x37, 0x1c, 0x22, 0x1d, 0x0a, 0x1e, 0xf3, 0x1e, + 0xda, 0x1f, 0xca, 0x20, 0xb1, 0x21, 0x96, 0x22, 0x70, 0x23, 0x55, 0x24, + 0x39, 0x25, 0x39, 0x26, 0x1a, 0x27, 0x07, 0x28, 0xe1, 0x28, 0xc5, 0x29, + 0xa7, 0x2a, 0x85, 0x2b, 0x70, 0x2c, 0x4e, 0x2d, 0x3e, 0x2e, 0x19, 0x2f, + 0xf3, 0x2f, 0xdf, 0x30, 0xc0, 0x31, 0xaf, 0x32, 0x93, 0x33, 0x77, 0x34, + 0x48, 0x35, 0x2a, 0x36, 0x0f, 0x37, 0xf8, 0x37, 0xd9, 0x38, 0xbe, 0x39, + 0x8b, 0x3a, 0x74, 0x3b, 0x48, 0x3c, 0x2d, 0x3d, 0xfa, 0x3d, 0xe7, 0x3e, + 0xb0, 0x3f, 0x98, 0x40, 0x67, 0x41, 0x3a, 0x42, 0x16, 0x43, 0xf4, 0x43, + 0xd8, 0x44, 0xa4, 0x45, 0x7c, 0x46, 0x4c, 0x47, 0x2a, 0x48, 0x06, 0x49, + 0xce, 0x49, 0xa5, 0x4a, 0x77, 0x4b, 0x4e, 0x4c, 0x13, 0x4d, 0xdf, 0x4d, + 0xaa, 0x4e, 0x74, 0x4f, 0x3d, 0x50, 0xfc, 0x50, 0xbd, 0x51, 0x8c, 0x52, + 0x3e, 0x53, 0xfe, 0x53, 0x99, 0x54, 0x57, 0x55, 0xfc, 0x55, 0xab, 0x56, + 0x45, 0x57, 0xd6, 0x57, 0x87, 0x58, 0x2f, 0x59, 0xbf, 0x59, 0x48, 0x5a, + 0xc7, 0x5a, 0x54, 0x5b, 0xc8, 0x5b, 0x45, 0x5c, 0xb4, 0x5c, 0x25, 0x5d, + 0x7e, 0x5d, 0xda, 0x5d, 0x36, 0x5e, 0xa5, 0x5e, 0xe9, 0x5e, 0x37, 0x5f, + 0x72, 0x5f, 0xab, 0x5f, 0xe5, 0x5f, 0x1d, 0x60, 0x4f, 0x60, 0x81, 0x60, + 0x9c, 0x60, 0xc3, 0x60, 0xdc, 0x60, 0xf7, 0x60, 0x04, 0x61, 0x16, 0x61, + 0x1b, 0x61, 0x21, 0x61, 0x20, 0x61, 0x0d, 0x61, 0x0b, 0x61, 0xf0, 0x60, + 0xe5, 0x60, 0xc7, 0x60, 0xb3, 0x60, 0x98, 0x60, 0x7c, 0x60, 0x59, 0x60, + 0x4c, 0x60, 0x24, 0x60, 0x0d, 0x60, 0xdf, 0x5f, 0xb7, 0x5f, 0x87, 0x5f, + 0x6b, 0x5f, 0x44, 0x5f, 0x28, 0x5f, 0xf5, 0x5e, 0xbd, 0x5e, 0x8f, 0x5e, + 0x5c, 0x5e, 0x2a, 0x5e, 0xfe, 0x5d, 0xcd, 0x5d, 0xa4, 0x5d, 0x75, 0x5d, + 0x4d, 0x5d, 0x11, 0x5d, 0xdf, 0x5c, 0xa9, 0x5c, 0x78, 0x5c, 0x42, 0x5c, + 0x13, 0x5c, 0xde, 0x5b, 0xaf, 0x5b, 0x75, 0x5b, 0x3e, 0x5b, 0xfd, 0x5a, + 0xbc, 0x5a, 0x90, 0x5a, 0x54, 0x5a, 0x1f, 0x5a, 0xe5, 0x59, 0xc2, 0x59, + 0x80, 0x59, 0x39, 0x59, 0x0a, 0x59, 0xd6, 0x58, 0x96, 0x58, 0x55, 0x58, + 0x1e, 0x58, 0xf1, 0x57, 0xc8, 0x57, 0x7e, 0x57, 0x44, 0x57, 0x11, 0x57, + 0xd4, 0x56, 0x93, 0x56, 0x4c, 0x56, 0x11, 0x56, 0xd7, 0x55, 0xae, 0x55, + 0x72, 0x55, 0x3c, 0x55, 0x0c, 0x55, 0xd1, 0x54, 0x98, 0x54, 0x63, 0x54, + 0x2b, 0x54, 0xf8, 0x53, 0xc6, 0x53, 0x81, 0x53, 0x4b, 0x53, 0x19, 0x53, + 0xea, 0x52, 0xb2, 0x52, 0x7e, 0x52, 0x30, 0x52, 0xc5, 0x51, 0x46, 0x51, + 0xca, 0x50, 0x55, 0x50, 0xd7, 0x4f, 0x5d, 0x4f, 0xe4, 0x4e, 0x79, 0x4e, + 0xfb, 0x4d, 0x83, 0x4d, 0x02, 0x4d, 0x8a, 0x4c, 0x1f, 0x4c, 0x98, 0x4b, + 0x20, 0x4b, 0xa7, 0x4a, 0x36, 0x4a, 0xc0, 0x49, 0x44, 0x49, 0xc3, 0x48, + 0x44, 0x48, 0xd5, 0x47, 0x59, 0x47, 0xe6, 0x46, 0x63, 0x46, 0xf8, 0x45, + 0x79, 0x45, 0xfa, 0x44, 0x80, 0x44, 0x01, 0x44, 0x7a, 0x43, 0x04, 0x43, + 0x85, 0x42, 0x07, 0x42, 0x92, 0x41, 0x17, 0x41, 0x94, 0x40, 0x16, 0x40, + 0x9f, 0x3f, 0x20, 0x3f, 0x9c, 0x3e, 0x29, 0x3e, 0x9c, 0x3d, 0x20, 0x3d, + 0x88, 0x3c, 0x0c, 0x3c, 0x87, 0x3b, 0x07, 0x3b, 0x89, 0x3a, 0xfb, 0x39, + 0x6f, 0x39, 0xe7, 0x38, 0x55, 0x38, 0xcf, 0x37, 0x43, 0x37, 0xb5, 0x36, + 0x2a, 0x36, 0x9c, 0x35, 0x0a, 0x35, 0x83, 0x34, 0xe6, 0x33, 0x53, 0x33, + 0xba, 0x32, 0x1d, 0x32, 0x78, 0x31, 0xcb, 0x30, 0x34, 0x30, 0x8e, 0x2f, + 0xf6, 0x2e, 0x56, 0x2e, 0xab, 0x2d, 0xfe, 0x2c, 0x4c, 0x2c, 0x9f, 0x2b, + 0xed, 0x2a, 0x36, 0x2a, 0x7b, 0x29, 0xb9, 0x28, 0x02, 0x28, 0x41, 0x27, + 0x81, 0x26, 0xb9, 0x25, 0xfb, 0x24, 0x2d, 0x24, 0x66, 0x23, 0x98, 0x22, + 0xc6, 0x21, 0xe9, 0x20, 0x0d, 0x20, 0x28, 0x1f, 0x4c, 0x1e, 0x64, 0x1d, + 0x66, 0x1c, 0x8c, 0x1b, 0x96, 0x1a, 0xac, 0x19, 0xb2, 0x18, 0xbb, 0x17, + 0xc2, 0x16, 0xc7, 0x15, 0xcb, 0x14, 0xcd, 0x13, 0xc4, 0x12, 0xca, 0x11, + 0xb6, 0x10, 0xb8, 0x0f, 0xa3, 0x0e, 0x9e, 0x0d, 0x88, 0x0c, 0x86, 0x0b, + 0x7b, 0x0a, 0x7c, 0x09, 0x6d, 0x08, 0x5b, 0x07, 0x4a, 0x06, 0x38, 0x05, + 0x2f, 0x04, 0x1c, 0x03, 0x10, 0x02, 0xf6, 0x00, 0xe9, 0xff, 0xe5, 0xfe, + 0xcf, 0xfd, 0xc8, 0xfc, 0xb1, 0xfb, 0xa7, 0xfa, 0x8d, 0xf9, 0x7b, 0xf8, + 0x7e, 0xf7, 0x77, 0xf6, 0x68, 0xf5, 0x62, 0xf4, 0x49, 0xf3, 0x42, 0xf2, + 0x41, 0xf1, 0x3e, 0xf0, 0x49, 0xef, 0x47, 0xee, 0x56, 0xed, 0x46, 0xec, + 0x56, 0xeb, 0x5c, 0xea, 0x6c, 0xe9, 0x7d, 0xe8, 0x9c, 0xe7, 0x99, 0xe6, + 0xbf, 0xe5, 0xc9, 0xe4, 0xe5, 0xe3, 0xfd, 0xe2, 0x17, 0xe2, 0x26, 0xe1, + 0x44, 0xe0, 0x6d, 0xdf, 0x9f, 0xde, 0xc5, 0xdd, 0xec, 0xdc, 0x26, 0xdc, + 0x58, 0xdb, 0x91, 0xda, 0xb7, 0xd9, 0xf5, 0xd8, 0x27, 0xd8, 0x63, 0xd7, + 0x96, 0xd6, 0xd5, 0xd5, 0x1a, 0xd5, 0x52, 0xd4, 0x9d, 0xd3, 0xde, 0xd2, + 0x27, 0xd2, 0x6c, 0xd1, 0xb3, 0xd0, 0xf6, 0xcf, 0x51, 0xcf, 0x98, 0xce, + 0xe9, 0xcd, 0x2f, 0xcd, 0x88, 0xcc, 0xdc, 0xcb, 0x41, 0xcb, 0x9f, 0xca, + 0x01, 0xca, 0x60, 0xc9, 0xc4, 0xc8, 0x13, 0xc8, 0x7e, 0xc7, 0xe2, 0xc6, + 0x51, 0xc6, 0xb6, 0xc5, 0x1a, 0xc5, 0x8e, 0xc4, 0xf6, 0xc3, 0x74, 0xc3, + 0xdf, 0xc2, 0x59, 0xc2, 0xd2, 0xc1, 0x47, 0xc1, 0xbe, 0xc0, 0x3b, 0xc0, + 0xbe, 0xbf, 0x3e, 0xbf, 0xc4, 0xbe, 0x39, 0xbe, 0xbf, 0xbd, 0x3e, 0xbd, + 0xd7, 0xbc, 0x5d, 0xbc, 0xec, 0xbb, 0x73, 0xbb, 0x07, 0xbb, 0x96, 0xba, + 0x24, 0xba, 0xb5, 0xb9, 0x49, 0xb9, 0xdd, 0xb8, 0x76, 0xb8, 0x02, 0xb8, + 0xa8, 0xb7, 0x3c, 0xb7, 0xee, 0xb6, 0x82, 0xb6, 0x2b, 0xb6, 0xc3, 0xb5, + 0x6e, 0xb5, 0x14, 0xb5, 0xc4, 0xb4, 0x6b, 0xb4, 0x20, 0xb4, 0xd2, 0xb3, + 0x78, 0xb3, 0x2c, 0xb3, 0xe6, 0xb2, 0x9e, 0xb2, 0x58, 0xb2, 0x1a, 0xb2, + 0xea, 0xb1, 0xa6, 0xb1, 0x63, 0xb1, 0x2b, 0xb1, 0xf3, 0xb0, 0xb8, 0xb0, + 0x7b, 0xb0, 0x4e, 0xb0, 0x20, 0xb0, 0xf9, 0xaf, 0xc6, 0xaf, 0xa2, 0xaf, + 0x84, 0xaf, 0x5e, 0xaf, 0x44, 0xaf, 0x21, 0xaf, 0x06, 0xaf, 0xe9, 0xae, + 0xe2, 0xae, 0xd0, 0xae, 0xc3, 0xae, 0xba, 0xae, 0xc1, 0xae, 0xaf, 0xae, + 0xbc, 0xae, 0xb5, 0xae, 0xc0, 0xae, 0xc3, 0xae, 0xd7, 0xae, 0xdd, 0xae, + 0xfb, 0xae, 0x0a, 0xaf, 0x16, 0xaf, 0x37, 0xaf, 0x4a, 0xaf, 0x70, 0xaf, + 0x86, 0xaf, 0xa9, 0xaf, 0xc7, 0xaf, 0xec, 0xaf, 0x12, 0xb0, 0x42, 0xb0, + 0x66, 0xb0, 0x91, 0xb0, 0xc0, 0xb0, 0xee, 0xb0, 0x1a, 0xb1, 0x4c, 0xb1, + 0x77, 0xb1, 0xb3, 0xb1, 0xdd, 0xb1, 0x10, 0xb2, 0x47, 0xb2, 0x70, 0xb2, + 0xb8, 0xb2, 0xef, 0xb2, 0x26, 0xb3, 0x64, 0xb3, 0x90, 0xb3, 0xd8, 0xb3, + 0x07, 0xb4, 0x4b, 0xb4, 0x83, 0xb4, 0xc7, 0xb4, 0xf4, 0xb4, 0x35, 0xb5, + 0x70, 0xb5, 0xbc, 0xb5, 0xf0, 0xb5, 0x39, 0xb6, 0x7d, 0xb6, 0xb7, 0xb6, + 0xfa, 0xb6, 0x2e, 0xb7, 0x7d, 0xb7, 0xbb, 0xb7, 0x01, 0xb8, 0x39, 0xb8, + 0x80, 0xb8, 0xbd, 0xb8, 0x05, 0xb9, 0x46, 0xb9, 0x94, 0xb9, 0xcd, 0xb9, + 0x17, 0xba, 0x5b, 0xba, 0x9e, 0xba, 0xdf, 0xba, 0x27, 0xbb, 0x6a, 0xbb, + 0xbc, 0xbb, 0xf6, 0xbb, 0x3a, 0xbc, 0x83, 0xbc, 0xc3, 0xbc, 0x16, 0xbd, + 0x58, 0xbd, 0xa2, 0xbd, 0xe0, 0xbd, 0x24, 0xbe, 0x70, 0xbe, 0xa1, 0xbe, + 0xfa, 0xbe, 0x37, 0xbf, 0x8d, 0xbf, 0xc9, 0xbf, 0x1d, 0xc0, 0x5d, 0xc0, + 0xa6, 0xc0, 0xe6, 0xc0, 0x2f, 0xc1, 0x7a, 0xc1, 0xcb, 0xc1, 0x2f, 0xc2, + 0x95, 0xc2, 0xfa, 0xc2, 0x55, 0xc3, 0xbb, 0xc3, 0x1e, 0xc4, 0x86, 0xc4, + 0xec, 0xc4, 0x4b, 0xc5, 0xab, 0xc5, 0x04, 0xc6, 0x72, 0xc6, 0xc6, 0xc6, + 0x3a, 0xc7, 0x8e, 0xc7, 0xfd, 0xc7, 0x5a, 0xc8, 0xc0, 0xc8, 0x17, 0xc9, + 0x79, 0xc9, 0xd5, 0xc9, 0x43, 0xca, 0x98, 0xca, 0x05, 0xcb, 0x64, 0xcb, + 0xc3, 0xcb, 0x1e, 0xcc, 0x81, 0xcc, 0xe3, 0xcc, 0x40, 0xcd, 0xa6, 0xcd, + 0x0a, 0xce, 0x6a, 0xce, 0xc0, 0xce, 0x26, 0xcf, 0x81, 0xcf, 0xf0, 0xcf, + 0x48, 0xd0, 0xad, 0xd0, 0x07, 0xd1, 0x71, 0xd1, 0xca, 0xd1, 0x2b, 0xd2, + 0x8a, 0xd2, 0xed, 0xd2, 0x50, 0xd3, 0xa1, 0xd3, 0x0f, 0xd4, 0x6f, 0xd4, + 0xd6, 0xd4, 0x30, 0xd5, 0x93, 0xd5, 0xf6, 0xd5, 0x55, 0xd6, 0xb5, 0xd6, + 0x12, 0xd7, 0x7b, 0xd7, 0xde, 0xd7, 0x34, 0xd8, 0x93, 0xd8, 0xe9, 0xd8, + 0x61, 0xd9, 0xbb, 0xd9, 0x2b, 0xda, 0x88, 0xda, 0xeb, 0xda, 0x4f, 0xdb, + 0xb9, 0xdb, 0x21, 0xdc, 0x80, 0xdc, 0xf7, 0xdc, 0x53, 0xdd, 0xbb, 0xdd, + 0x2b, 0xde, 0xa4, 0xde, 0x05, 0xdf, 0x74, 0xdf, 0xd8, 0xdf, 0x44, 0xe0, + 0xb4, 0xe0, 0x26, 0xe1, 0x91, 0xe1, 0x01, 0xe2, 0x77, 0xe2, 0xeb, 0xe2, + 0x5e, 0xe3, 0xc7, 0xe3, 0x44, 0xe4, 0xb2, 0xe4, 0x25, 0xe5, 0xa3, 0xe5, + 0x15, 0xe6, 0x97, 0xe6, 0x0b, 0xe7, 0x8b, 0xe7, 0x10, 0xe8, 0x7d, 0xe8, + 0x06, 0xe9, 0x74, 0xe9, 0xff, 0xe9, 0x82, 0xea, 0x01, 0xeb, 0x85, 0xeb, + 0xfa, 0xeb, 0x91, 0xec, 0x07, 0xed, 0x8f, 0xed, 0x15, 0xee, 0x9a, 0xee, + 0x26, 0xef, 0xa5, 0xef, 0x26, 0xf0, 0xb2, 0xf0, 0x3e, 0xf1, 0xca, 0xf1, + 0x45, 0xf2, 0xcc, 0xf2, 0x51, 0xf3, 0xdc, 0xf3, 0x5c, 0xf4, 0xe8, 0xf4, + 0x6e, 0xf5, 0xf9, 0xf5, 0x79, 0xf6, 0xf9, 0xf6, 0x7d, 0xf7, 0x08, 0xf8, + 0x91, 0xf8, 0x18, 0xf9, 0x95, 0xf9, 0x18, 0xfa, 0xa5, 0xfa, 0x21, 0xfb, + 0xa9, 0xfb, 0x2a, 0xfc, 0xa7, 0xfc, 0x23, 0xfd, 0xa3, 0xfd, 0x2b, 0xfe, + 0x9c, 0xfe, 0x2b, 0xff, 0xa0, 0xff, 0x1c, 0x00, 0x9a, 0x00, 0x11, 0x01, + 0x9a, 0x01, 0x14, 0x02, 0x8c, 0x02, 0x07, 0x03, 0x84, 0x03, 0xf7, 0x03, + 0x75, 0x04, 0xf3, 0x04, 0x65, 0x05, 0xe8, 0x05, 0x54, 0x06, 0xd3, 0x06, + 0x48, 0x07, 0xc2, 0x07, 0x38, 0x08, 0xad, 0x08, 0x28, 0x09, 0x99, 0x09, + 0x11, 0x0a, 0x79, 0x0a, 0xf5, 0x0a, 0x5c, 0x0b, 0xd1, 0x0b, 0x3f, 0x0c, + 0xb5, 0x0c, 0x2c, 0x0d, 0x9a, 0x0d, 0x0b, 0x0e, 0x74, 0x0e, 0xe6, 0x0e, + 0x45, 0x0f, 0xbd, 0x0f, 0x2f, 0x10, 0x9a, 0x10, 0x05, 0x11, 0x6c, 0x11, + 0xdb, 0x11, 0x40, 0x12, 0xaa, 0x12, 0x14, 0x13, 0x81, 0x13, 0xe9, 0x13, + 0x4d, 0x14, 0xb9, 0x14, 0x18, 0x15, 0x88, 0x15, 0xe6, 0x15, 0x58, 0x16, + 0xb9, 0x16, 0x1c, 0x17, 0x7e, 0x17, 0xe3, 0x17, 0x43, 0x18, 0xac, 0x18, + 0x08, 0x19, 0x6d, 0x19, 0xce, 0x19, 0x34, 0x1a, 0x90, 0x1a, 0xf5, 0x1a, + 0x53, 0x1b, 0xbb, 0x1b, 0x07, 0x1c, 0x6f, 0x1c, 0xc2, 0x1c, 0x28, 0x1d, + 0x84, 0x1d, 0xe8, 0x1d, 0x35, 0x1e, 0xa2, 0x1e, 0xf8, 0x1e, 0x59, 0x1f, + 0xb8, 0x1f, 0x0c, 0x20, 0x69, 0x20, 0xbe, 0x20, 0x19, 0x21, 0x66, 0x21, + 0xc6, 0x21, 0x1f, 0x22, 0x70, 0x22, 0xbe, 0x22, 0x18, 0x23, 0x72, 0x23, + 0xbf, 0x23, 0x0f, 0x24, 0x67, 0x24, 0xc0, 0x24, 0x08, 0x25, 0x51, 0x25, + 0xa6, 0x25, 0xf4, 0x25, 0x42, 0x26, 0x93, 0x26, 0xd6, 0x26, 0x25, 0x27, + 0x6c, 0x27, 0xb7, 0x27, 0x07, 0x28, 0x49, 0x28, 0x96, 0x28, 0xda, 0x28, + 0x22, 0x29, 0x66, 0x29, 0xa4, 0x29, 0xe8, 0x29, 0x20, 0x2a, 0x62, 0x2a, + 0xa9, 0x2a, 0xe5, 0x2a, 0x21, 0x2b, 0x5a, 0x2b, 0x97, 0x2b, 0xc1, 0x2b, + 0xfe, 0x2b, 0x28, 0x2c, 0x57, 0x2c, 0x88, 0x2c, 0xae, 0x2c, 0xd3, 0x2c, + 0xfa, 0x2c, 0x17, 0x2d, 0x33, 0x2d, 0x4b, 0x2d, 0x5d, 0x2d, 0x68, 0x2d, + 0x81, 0x2d, 0x92, 0x2d, 0x9e, 0x2d, 0xa9, 0x2d, 0xbb, 0x2d, 0xc3, 0x2d, + 0xcd, 0x2d, 0xd5, 0x2d, 0xcd, 0x2d, 0xdc, 0x2d, 0xe3, 0x2d, 0xe1, 0x2d, + 0xdd, 0x2d, 0xd9, 0x2d, 0xd7, 0x2d, 0xcf, 0x2d, 0xe0, 0x2d, 0xd2, 0x2d, + 0xd2, 0x2d, 0xcb, 0x2d, 0xb7, 0x2d, 0xb6, 0x2d, 0xa1, 0x2d, 0x9e, 0x2d, + 0x8b, 0x2d, 0x84, 0x2d, 0x68, 0x2d, 0x6a, 0x2d, 0x4e, 0x2d, 0x45, 0x2d, + 0x2f, 0x2d, 0x18, 0x2d, 0x15, 0x2d, 0xef, 0x2c, 0xe8, 0x2c, 0xc9, 0x2c, + 0xc7, 0x2c, 0xaa, 0x2c, 0x9b, 0x2c, 0x7c, 0x2c, 0x64, 0x2c, 0x3c, 0x2c, + 0x2e, 0x2c, 0x16, 0x2c, 0x05, 0x2c, 0xe1, 0x2b, 0xc8, 0x2b, 0xb5, 0x2b, + 0x9a, 0x2b, 0x7c, 0x2b, 0x61, 0x2b, 0x3f, 0x2b, 0x21, 0x2b, 0x01, 0x2b, + 0xee, 0x2a, 0xd0, 0x2a, 0xb3, 0x2a, 0x95, 0x2a, 0x6d, 0x2a, 0x50, 0x2a, + 0x2b, 0x2a, 0x0b, 0x2a, 0xe9, 0x29, 0xd1, 0x29, 0xa8, 0x29, 0x97, 0x29, + 0x6c, 0x29, 0x51, 0x29, 0x24, 0x29, 0x03, 0x29, 0xe6, 0x28, 0xbe, 0x28, + 0xa1, 0x28, 0x80, 0x28, 0x64, 0x28, 0x38, 0x28, 0x12, 0x28, 0xf0, 0x27, + 0xd3, 0x27, 0xac, 0x27, 0x94, 0x27, 0x67, 0x27, 0x4a, 0x27, 0x1c, 0x27, + 0xf7, 0x26, 0xd1, 0x26, 0xb6, 0x26, 0x8d, 0x26, 0x6e, 0x26, 0x4b, 0x26, + 0x25, 0x26, 0x02, 0x26, 0xd8, 0x25, 0xbe, 0x25, 0x93, 0x25, 0x7c, 0x25, + 0x4a, 0x25, 0x27, 0x25, 0x07, 0x25, 0xdc, 0x24, 0xbb, 0x24, 0x9a, 0x24, + 0x78, 0x24, 0x4c, 0x24, 0x26, 0x24, 0x00, 0x24, 0xd7, 0x23, 0xc0, 0x23, + 0x94, 0x23, 0x71, 0x23, 0x45, 0x23, 0x1c, 0x23, 0x00, 0x23, 0xd4, 0x22, + 0xb5, 0x22, 0x8e, 0x22, 0x67, 0x22, 0x39, 0x22, 0x00, 0x22, 0xbd, 0x21, + 0x87, 0x21, 0x46, 0x21, 0x01, 0x21, 0xca, 0x20, 0x89, 0x20, 0x4a, 0x20, + 0x17, 0x20, 0xd6, 0x1f, 0x9a, 0x1f, 0x5e, 0x1f, 0x20, 0x1f, 0xe0, 0x1e, + 0xa3, 0x1e, 0x5f, 0x1e, 0x29, 0x1e, 0xf0, 0x1d, 0xb8, 0x1d, 0x78, 0x1d, + 0x36, 0x1d, 0x04, 0x1d, 0xc6, 0x1c, 0x8b, 0x1c, 0x4d, 0x1c, 0x18, 0x1c, + 0xd9, 0x1b, 0x97, 0x1b, 0x5c, 0x1b, 0x2b, 0x1b, 0xf4, 0x1a, 0xb1, 0x1a, + 0x7c, 0x1a, 0x32, 0x1a, 0x02, 0x1a, 0xc6, 0x19, 0x8b, 0x19, 0x59, 0x19, + 0x10, 0x19, 0xd7, 0x18, 0x9c, 0x18, 0x62, 0x18, 0x22, 0x18, 0xe8, 0x17, + 0xb1, 0x17, 0x7c, 0x17, 0x34, 0x17, 0xf9, 0x16, 0xc0, 0x16, 0x8b, 0x16, + 0x55, 0x16, 0x14, 0x16, 0xdd, 0x15, 0x9f, 0x15, 0x65, 0x15, 0x2b, 0x15, + 0xea, 0x14, 0xb9, 0x14, 0x70, 0x14, 0x3d, 0x14, 0x05, 0x14, 0xc1, 0x13, + 0x86, 0x13, 0x45, 0x13, 0x09, 0x13, 0xca, 0x12, 0x90, 0x12, 0x57, 0x12, + 0x1a, 0x12, 0xe1, 0x11, 0x9b, 0x11, 0x61, 0x11, 0x1d, 0x11, 0xe1, 0x10, + 0x9d, 0x10, 0x64, 0x10, 0x17, 0x10, 0xde, 0x0f, 0xa1, 0x0f, 0x60, 0x0f, + 0x1b, 0x0f, 0xd8, 0x0e, 0x90, 0x0e, 0x5b, 0x0e, 0x0e, 0x0e, 0xd3, 0x0d, + 0x86, 0x0d, 0x4d, 0x0d, 0xf5, 0x0c, 0xba, 0x0c, 0x68, 0x0c, 0x2a, 0x0c, + 0xde, 0x0b, 0x94, 0x0b, 0x4e, 0x0b, 0x07, 0x0b, 0xbb, 0x0a, 0x6c, 0x0a, + 0x25, 0x0a, 0xd4, 0x09, 0x89, 0x09, 0x39, 0x09, 0xe6, 0x08, 0xa3, 0x08, + 0x4f, 0x08, 0x02, 0x08, 0xa7, 0x07, 0x5f, 0x07, 0x08, 0x07, 0xba, 0x06, + 0x68, 0x06, 0x1f, 0x06, 0xc5, 0x05, 0x7a, 0x05, 0x1f, 0x05, 0xd7, 0x04, + 0x85, 0x04, 0x31, 0x04, 0xde, 0x03, 0x89, 0x03, 0x3a, 0x03, 0xe9, 0x02, + 0x96, 0x02, 0x47, 0x02, 0xf7, 0x01, 0xa4, 0x01, 0x5d, 0x01, 0x06, 0x01, + 0xb9, 0x00, 0x00, 0x00 +}; +unsigned int kick_raw_len = 6352; diff --git a/third-party/TeensyVariablePlayback/extras/soundio/save_wav/CMakeLists.txt b/third-party/TeensyVariablePlayback/extras/soundio/save_wav/CMakeLists.txt new file mode 100644 index 0000000..837c98e --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/soundio/save_wav/CMakeLists.txt @@ -0,0 +1,59 @@ +cmake_minimum_required(VERSION 3.10) +set(CMAKE_CXX_STANDARD 11) +project(save_wav) + +find_package(teensy_x86_stubs) +include_directories(${teensy_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_x86_sd_stubs) +include_directories(${teensy_x86_sd_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs) +include_directories(${teensy_audio_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs_soundio) +if(teensy_audio_x86_stubs_soundio_FOUND) + include_directories(${teensy_audio_x86_stubs_soundio_INCLUDE_DIR}) + + include_directories(/usr/local/include) #soundio + include_directories(../../../src) + + add_custom_command(OUTPUT stereo_souljah_wav.c + COMMAND embedfile stereo_souljah_wav ${CMAKE_SOURCE_DIR}/test/resources/input/stereo_souljah.wav + ) + + add_custom_command(OUTPUT mono_souljah_wav.c + COMMAND embedfile mono_souljah_wav ${CMAKE_SOURCE_DIR}/test/resources/input/mono_souljah.wav + ) + + add_executable(save_wav mono_souljah_wav.c stereo_souljah_wav.c save_wav.cpp) + target_link_libraries(save_wav teensy_variable_playback) + + if(WIN32) + elseif(UNIX AND NOT APPLE) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") + SET(SOUNDIO_LIBS -L/usr/lib/x86_64-linux-gnu -lsoundio) + elseif(APPLE) + INCLUDE_DIRECTORIES(/System/Library/Frameworks) + FIND_LIBRARY(glfw3_LIBRARY glfw) + FIND_LIBRARY(COCOA_LIBRARY Cocoa) + FIND_LIBRARY(OpenGL_LIBRARY OpenGL) + FIND_LIBRARY(IOKit_LIBRARY IOKit) + FIND_LIBRARY(glew_LIBRARY glew) + FIND_LIBRARY(CoreVideo_LIBRARY CoreVideo) + MARK_AS_ADVANCED(COCOA_LIBRARY OpenGL_LIBRARY) + FIND_LIBRARY(FREETYPE_LIBRARIES FreeType) + SET(APPLE_LIBS ${COCOA_LIBRARY} ${IOKit_LIBRARY} ${OpenGL_LIBRARY} ${CoreVideo_LIBRARY}) + SET(APPLE_LIBS ${APPLE_LIBS} ${GLFW3_LIBRARY} ${ASSIMP_LIBRARY} ${FREETYPE_LIBRARIES} ${glfw3_LIBRARY} ${glew_LIBRARY}) + set(LIBS ${LIBS} ${APPLE_LIBS}) + target_link_libraries(save_wav + "-framework CoreServices" + "-framework CoreAudio" + "-framework Foundation" + "-framework AudioUnit") + SET(SOUNDIO_LIBS /usr/local/lib/libsoundio.a) + endif() + + target_link_libraries(save_wav ${LIBS} ${teensy_x86_stubs_LIBS} ${teensy_x86_sd_stubs_LIBS} ${teensy_audio_x86_stubs_LIBS} ${teensy_audio_x86_stubs_soundio_LIBS} ${teensy_st7735_linux_stubs_LIBS} ${teensy_st7735_linux_extras_opengl_LIBS} ${SOUNDIO_LIBS}) +#set(CMAKE_VERBOSE_MAKEFILE 1) +endif() \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/extras/soundio/save_wav/save_wav.cpp b/third-party/TeensyVariablePlayback/extras/soundio/save_wav/save_wav.cpp new file mode 100644 index 0000000..fb70fdc --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/soundio/save_wav/save_wav.cpp @@ -0,0 +1,152 @@ +// Plays a RAW (16-bit signed) PCM audio file at slower or faster rate +// this example plays a sample stored in an array +#include +#include +#include "../../../src/playarrayresmp.h" +#include "output_soundio.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// GUItool: begin automatically generated code +AudioPlayArrayResmp rraw_a1; //xy=306,225 +AudioRecordQueue queue1; //xy=609,267 +AudioOutputSoundIO sio_out1; //xy=612,224 +AudioConnection patchCord1(rraw_a1, 0, sio_out1, 0); +AudioConnection patchCord2(rraw_a1, 0, sio_out1, 1); +AudioConnection patchCord3(rraw_a1, 0, queue1, 0); +// GUItool: end automatically generated code + +extern unsigned int mono_souljah_wav_len; +extern unsigned char mono_souljah_wav[]; + +int16_t buffer[512] = {0}; +File frec; + +unsigned long lastSamplePlayed = 0; +void my_handler(sig_atomic_t i); +static char stack_body[64*1024]; +static stack_t sigseg_stack; +static struct sigaction sigseg_handler; + +void crash_handler(sig_atomic_t i); + +void setup() { + Serial.begin(9600); + + rraw_a1.setPlaybackRate(1.0f); + rraw_a1.enableInterpolation(true); + //rraw_a1.play((int16_t*)kick_raw, kick_raw_len/2); + Serial.println("setup done"); + + if (SD.exists("RECORD.RAW")) { + // The SD library writes new data to the end of the + // file, so to start a new recording, the old file + // must be deleted before new data is written. + SD.remove("RECORD.RAW"); + } + frec = SD.open("RECORD.RAW", O_WRITE); + + AudioMemory(120); + + if (frec) { + queue1.begin(); + Serial.println("startRecording"); + } else { + Serial.println("recording failed..."); + } +} + +void loop() { + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 1000) { + if (!rraw_a1.isPlaying()) { + rraw_a1.playWav((int16_t *)mono_souljah_wav, mono_souljah_wav_len/2); + lastSamplePlayed = currentMillis; + + Serial.print("Memory: "); + Serial.print(AudioMemoryUsage()); + Serial.print(","); + Serial.print(AudioMemoryUsageMax()); + Serial.println(); + } + } + + if (queue1.available() >= 1) { + int16_t* incomming = queue1.readBuffer(); + if (incomming != NULL) { + memcpy(buffer, incomming, 256); + queue1.freeBuffer(); + frec.write((unsigned char *)buffer, 256); + frec.flush(); + } + } + delay(1); +} + +int main() { + signal (SIGINT,my_handler); + signal (SIGSEGV,crash_handler); + + sigseg_stack.ss_sp = stack_body; + sigseg_stack.ss_flags = SS_ONSTACK; + sigseg_stack.ss_size = sizeof(stack_body); + // assert(!sigaltstack(&sigseg_stack, nullptr)); + sigseg_handler.sa_flags = SA_ONSTACK; + sigseg_handler.sa_handler = &crash_handler; + // assert(!sigaction(SIGSEGV, &sigseg_handler, nullptr)); + + initialize_mock_arduino(); + SD.setSDCardFolderPath("."); + setup(); + while(!arduino_should_exit){ + loop(); + } + delay(1000); + frec.close(); +} + +void my_handler(sig_atomic_t i){ + if ( i== SIGINT) { + arduino_should_exit = true; + printf("Caught signal %d\n",i); + } else + { + cerr << "sig seg fault handler" << endl; + const int asize = 10; + void *array[asize]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, asize); + + // print out all the frames to stderr + cerr << "stack trace: " << endl; + backtrace_symbols_fd(array, size, STDERR_FILENO); + cerr << "resend SIGSEGV to get core dump" << endl; + signal(i, SIG_DFL); + kill(getpid(), i); + } +} +void crash_handler(sig_atomic_t i){ + cerr << "sig seg fault handler" << endl; + const int asize = 10; + void *array[asize]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, asize); + + // print out all the frames to stderr + cerr << "stack trace: " << endl; + backtrace_symbols_fd(array, size, STDERR_FILENO); + cerr << "resend SIGSEGV to get core dump" << endl; + signal(i, SIG_DFL); + kill(getpid(), i); +} diff --git a/third-party/TeensyVariablePlayback/extras/soundio/sd_play_all/CMakeLists.txt b/third-party/TeensyVariablePlayback/extras/soundio/sd_play_all/CMakeLists.txt new file mode 100644 index 0000000..8b3cb8e --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/soundio/sd_play_all/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.10) +set(CMAKE_CXX_STANDARD 11) +project(sd_play_all) + +find_package(teensy_x86_stubs) +include_directories(${teensy_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_x86_sd_stubs) +include_directories(${teensy_x86_sd_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs) +include_directories(${teensy_audio_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs_soundio) +if(teensy_audio_x86_stubs_soundio_FOUND) + include_directories(${teensy_audio_x86_stubs_soundio_INCLUDE_DIR}) + + include_directories(../../../src) + include_directories(/usr/local/include) #soundio + + add_executable(sd_play_all sd_play_all.cpp) + target_link_libraries(sd_play_all teensy_variable_playback) + + if(WIN32) + elseif(UNIX AND NOT APPLE) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") + SET(SOUNDIO_LIBS -L/usr/lib/x86_64-linux-gnu -lsoundio) + elseif(APPLE) + INCLUDE_DIRECTORIES(/System/Library/Frameworks) + FIND_LIBRARY(glfw3_LIBRARY glfw) + FIND_LIBRARY(COCOA_LIBRARY Cocoa) + FIND_LIBRARY(OpenGL_LIBRARY OpenGL) + FIND_LIBRARY(IOKit_LIBRARY IOKit) + FIND_LIBRARY(glew_LIBRARY glew) + FIND_LIBRARY(CoreVideo_LIBRARY CoreVideo) + MARK_AS_ADVANCED(COCOA_LIBRARY OpenGL_LIBRARY) + FIND_LIBRARY(FREETYPE_LIBRARIES FreeType) + SET(APPLE_LIBS ${COCOA_LIBRARY} ${IOKit_LIBRARY} ${OpenGL_LIBRARY} ${CoreVideo_LIBRARY}) + SET(APPLE_LIBS ${APPLE_LIBS} ${GLFW3_LIBRARY} ${ASSIMP_LIBRARY} ${FREETYPE_LIBRARIES} ${glfw3_LIBRARY} ${glew_LIBRARY}) + set(LIBS ${LIBS} ${APPLE_LIBS}) + target_link_libraries(sd_play_all + "-framework CoreServices" + "-framework CoreAudio" + "-framework Foundation" + "-framework AudioUnit") + SET(SOUNDIO_LIBS /usr/local/lib/libsoundio.a) + endif() + + target_link_libraries(sd_play_all ${LIBS} ${teensy_x86_stubs_LIBS} ${teensy_x86_sd_stubs_LIBS} ${teensy_audio_x86_stubs_LIBS} ${teensy_audio_x86_stubs_soundio_LIBS} ${teensy_st7735_linux_stubs_LIBS} ${teensy_st7735_linux_extras_opengl_LIBS} ${SOUNDIO_LIBS}) + #set(CMAKE_VERBOSE_MAKEFILE 1) +endif() \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/extras/soundio/sd_play_all/sd_play_all.cpp b/third-party/TeensyVariablePlayback/extras/soundio/sd_play_all/sd_play_all.cpp new file mode 100644 index 0000000..f8fba59 --- /dev/null +++ b/third-party/TeensyVariablePlayback/extras/soundio/sd_play_all/sd_play_all.cpp @@ -0,0 +1,784 @@ +// Plays a RAW (16-bit signed) PCM audio file at slower or faster rate +// this example plays a sample stored in an array +#include +#include +#include "playsdresmp.h" +#include "output_soundio.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// GUItool: begin automatically generated code +AudioPlaySdResmp playSd1; //xy=306,225 +AudioRecordQueue queue1; //xy=609,267 +AudioOutputSoundIO sio_out1; //xy=612,224 +AudioConnection patchCord1(playSd1, 0, sio_out1, 0); +AudioConnection patchCord2(playSd1, 1, sio_out1, 1); +AudioConnection patchCord3(playSd1, 0, queue1, 0); +// GUItool: end automatically generated code + +char** _filenames = nullptr; +uint16_t _fileIndex = 0; +uint16_t _numWaveFiles = 0; + +int16_t buffer[512] = {0}; +File frec; + +unsigned long lastSamplePlayed = 0; +void my_handler(sig_atomic_t i); +static char stack_body[64*1024]; +static stack_t sigseg_stack; +static struct sigaction sigseg_handler; + +void crash_handler(sig_atomic_t i); + + + +uint16_t getNumWavFilesInDirectory(char *directory); +void populateFilenames(char *directory, char **filenames); + + +void setup() { + Serial.begin(9600); + + playSd1.setPlaybackRate(1.0f); + playSd1.enableInterpolation(true); + //rraw_a1.play((int16_t*)kick_raw, kick_raw_len/2); + Serial.println("setup done"); + + if (SD.exists("RECORD_SD.RAW")) { + // The SD library writes new data to the end of the + // file, so to start a new recording, the old file + // must be deleted before new data is written. + SD.remove("RECORD_SD.RAW"); + } + frec = SD.open("RECORD_SD.RAW", O_WRITE); + + _numWaveFiles = getNumWavFilesInDirectory("/"); + Serial.printf("Num wave files: %d\n", _numWaveFiles); + _filenames = new char*[_numWaveFiles]; + populateFilenames("/", _filenames); + + Serial.println("Populated..."); + + AudioMemory(120); + + if (frec) { + queue1.begin(); + Serial.println("startRecording"); + } else { + Serial.println("recording failed..."); + } +} + +void loop() { + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 1000) { + if (!playSd1.isPlaying()) { + if (playSd1.playWav(_filenames[_fileIndex])) { + lastSamplePlayed = currentMillis; + Serial.printf("playing %s\n", _filenames[_fileIndex]); + } else + Serial.printf("failed to play%s\n", _filenames[_fileIndex]); + _fileIndex++; + _fileIndex %= _numWaveFiles; + + Serial.print("Memory: "); + Serial.print(AudioMemoryUsage()); + Serial.print(","); + Serial.print(AudioMemoryUsageMax()); + Serial.println(); + } + } + + if (queue1.available() >= 1) { + int16_t* incomming = queue1.readBuffer(); + //Serial.printf("sizeof(incomming)=%i\n", sizeof(incomming)); + //if (incomming != NULL && sizeof(incomming) >= 256) { + if (incomming != NULL) { + memcpy(buffer, incomming, 256); + queue1.freeBuffer(); + frec.write((unsigned char *)buffer, 256); + frec.flush(); + } + //else { + // arduino_should_exit = true; + //Serial.printf("sizeof(incomming)=%i\n", sizeof(incomming)); + //} + } + delay(1); +} + +int main(int numArgs, char **args) { + + if (numArgs < 2) + { + std::cout << "usage: " << args[0] << " "; + exit(0); + } + std::cout << args[1] << std::endl; + signal (SIGINT,my_handler); + signal (SIGSEGV,crash_handler); + + sigseg_stack.ss_sp = stack_body; + sigseg_stack.ss_flags = SS_ONSTACK; + sigseg_stack.ss_size = sizeof(stack_body); + // assert(!sigaltstack(&sigseg_stack, nullptr)); + sigseg_handler.sa_flags = SA_ONSTACK; + sigseg_handler.sa_handler = &crash_handler; + // assert(!sigaction(SIGSEGV, &sigseg_handler, nullptr)); + + initialize_mock_arduino(); + //SD.setSDCardFileData((char *) kick_raw, kick_raw_len); + SD.setSDCardFolderPath(args[1]); + setup(); + while(!arduino_should_exit){ + loop(); + } + delay(1000); + frec.close(); +} + + +uint16_t getNumWavFilesInDirectory(char *directory) { + File dir = SD.open(directory); + uint16_t numWaveFiles = 0; + + while (true) { + + File files = dir.openNextFile(); + if (!files) { + //If no more files, break out. + break; + } + + String curfile = files.name(); //put file in string + + int m = curfile.lastIndexOf(".WAV"); + int a = curfile.lastIndexOf(".wav"); + int underscore = curfile.indexOf("_"); + int underscore2 = curfile.indexOf("._"); + // if returned results is more then 0 add them to the list. + if ((m > 0 || a > 0) && (underscore != 0) && (underscore2 != 0)) { + numWaveFiles++; + } + + files.close(); + } + // close + dir.close(); + return numWaveFiles; +} + +void populateFilenames(char *directory, char **filenames) { + File dir = SD.open(directory); + uint16_t index = 0; + + while (true) { + + File files = dir.openNextFile(); + if (!files) { + //If no more files, break out. + break; + } + + String curfile = files.name(); //put file in string + + int m = curfile.lastIndexOf(".WAV"); + int a = curfile.lastIndexOf(".wav"); + int underscore = curfile.indexOf("_"); + int underscore2 = curfile.indexOf("._"); + // if returned results is more then 0 add them to the list. + if ((m > 0 || a > 0) && (underscore != 0) && (underscore2 != 0) ) { + + Serial.printf(" ---- %s\n", curfile.c_str()); + filenames[index] = new char[curfile.length()+1] {0}; + memcpy(filenames[index], curfile.c_str(), curfile.length()+1); + Serial.printf(" ------ %s\n", filenames[index]); + index++; + } + files.close(); + } + // close + dir.close(); +} + + +void my_handler(sig_atomic_t i){ + if ( i== SIGINT) { + arduino_should_exit = true; + printf("Caught signal %d\n",i); + } else + { + cerr << "sig seg fault handler" << endl; + const int asize = 10; + void *array[asize]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, asize); + + // print out all the frames to stderr + cerr << "stack trace: " << endl; + backtrace_symbols_fd(array, size, STDERR_FILENO); + cerr << "resend SIGSEGV to get core dump" << endl; + signal(i, SIG_DFL); + kill(getpid(), i); + } +} +void crash_handler(sig_atomic_t i){ + cerr << "sig seg fault handler" << endl; + const int asize = 10; + void *array[asize]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, asize); + + // print out all the frames to stderr + cerr << "stack trace: " << endl; + backtrace_symbols_fd(array, size, STDERR_FILENO); + cerr << "resend SIGSEGV to get core dump" << endl; + signal(i, SIG_DFL); + kill(getpid(), i); +} + +unsigned char kick_raw[] = { + 0x99, 0x02, 0xd7, 0x02, 0xfa, 0x02, 0x5f, 0x03, 0xc1, 0x03, 0x2a, 0x04, + 0xad, 0x04, 0xa5, 0x05, 0x76, 0x06, 0x2f, 0x07, 0x9e, 0x07, 0xe2, 0x07, + 0x43, 0x08, 0x92, 0x08, 0xb2, 0x08, 0xe8, 0x08, 0x16, 0x09, 0xda, 0x08, + 0x51, 0x08, 0x01, 0x08, 0x25, 0x08, 0x70, 0x08, 0xc3, 0x08, 0x23, 0x09, + 0x95, 0x09, 0x19, 0x0a, 0x83, 0x0a, 0x7e, 0x0a, 0xd0, 0x0a, 0x65, 0x0b, + 0xf6, 0x0b, 0x89, 0x0c, 0xd1, 0x0c, 0xcf, 0x0c, 0x1a, 0x0d, 0xe5, 0x0d, + 0x5e, 0x0e, 0xbb, 0x0e, 0xec, 0x0e, 0xd9, 0x0e, 0x07, 0x0f, 0xc8, 0x0f, + 0x2a, 0x10, 0x04, 0x10, 0x28, 0x10, 0x54, 0x11, 0x8e, 0x13, 0x4b, 0x16, + 0x09, 0x19, 0x91, 0x1b, 0xf7, 0x1d, 0x55, 0x20, 0xd1, 0x22, 0xcb, 0x25, + 0x4d, 0x29, 0xa8, 0x2c, 0x7f, 0x2f, 0xda, 0x31, 0xac, 0x34, 0x0a, 0x3a, + 0x24, 0x47, 0x9d, 0x5b, 0xe9, 0x67, 0x29, 0x67, 0x24, 0x66, 0x26, 0x66, + 0xd2, 0x65, 0x9c, 0x65, 0x38, 0x65, 0x05, 0x65, 0x9f, 0x64, 0x64, 0x64, + 0x12, 0x64, 0xce, 0x63, 0x7c, 0x63, 0x32, 0x63, 0xe6, 0x62, 0x97, 0x62, + 0x49, 0x62, 0x01, 0x62, 0xb3, 0x61, 0x63, 0x61, 0x15, 0x61, 0xc4, 0x60, + 0x75, 0x60, 0x20, 0x60, 0xce, 0x5f, 0x7a, 0x5f, 0x28, 0x5f, 0xd5, 0x5e, + 0x81, 0x5e, 0x2d, 0x5e, 0xd3, 0x5d, 0x80, 0x5d, 0x2e, 0x5d, 0xe6, 0x5c, + 0x1a, 0x5c, 0x16, 0x5a, 0x01, 0x58, 0xb9, 0x56, 0x6d, 0x55, 0xf4, 0x53, + 0x49, 0x52, 0x83, 0x50, 0x87, 0x4e, 0x5f, 0x4c, 0x68, 0x4a, 0x5c, 0x48, + 0x62, 0x46, 0x5a, 0x44, 0xe2, 0x41, 0x08, 0x3f, 0x1c, 0x3c, 0x44, 0x39, + 0x35, 0x36, 0xcb, 0x32, 0xaf, 0x2f, 0xc8, 0x2c, 0xf8, 0x29, 0x55, 0x27, + 0x6a, 0x24, 0x0f, 0x21, 0x5e, 0x1d, 0xc3, 0x19, 0x7b, 0x16, 0x71, 0x13, + 0x6c, 0x10, 0x00, 0x0d, 0xd2, 0x08, 0x7f, 0x04, 0x7a, 0x01, 0x43, 0xff, + 0xb9, 0xfc, 0xfa, 0xf9, 0x3b, 0xf7, 0xcb, 0xf4, 0x2b, 0xf2, 0x02, 0xef, + 0x0c, 0xec, 0x3d, 0xe9, 0x21, 0xe6, 0xa6, 0xe2, 0x8a, 0xdf, 0x00, 0xdd, + 0xbc, 0xda, 0x9e, 0xd8, 0xc1, 0xd6, 0xd6, 0xd4, 0xd6, 0xd2, 0xad, 0xd0, + 0x5f, 0xce, 0xf0, 0xcb, 0xe9, 0xc9, 0x61, 0xc8, 0x75, 0xc7, 0x97, 0xc6, + 0x3e, 0xc5, 0x07, 0xc4, 0x8e, 0xc3, 0x18, 0xc3, 0x3a, 0xc2, 0x15, 0xc1, + 0x0e, 0xc0, 0xb3, 0xbf, 0xcf, 0xbf, 0xf8, 0xbf, 0xcc, 0xbf, 0x72, 0xbf, + 0x41, 0xbf, 0x2b, 0xbf, 0xe2, 0xbe, 0x99, 0xbe, 0x4e, 0xbe, 0x0e, 0xbe, + 0xcd, 0xbd, 0x7c, 0xbd, 0x8a, 0xbd, 0x88, 0xbd, 0x04, 0xbd, 0x0c, 0xbc, + 0xb3, 0xbb, 0xf6, 0xbb, 0xf1, 0xbb, 0x12, 0xbc, 0x6f, 0xbc, 0xcb, 0xbc, + 0xe4, 0xbc, 0x33, 0xbd, 0x1b, 0xbe, 0xac, 0xbe, 0x1e, 0xbf, 0x91, 0xbf, + 0x50, 0xc0, 0x40, 0xc1, 0x3d, 0xc2, 0x32, 0xc3, 0xdf, 0xc3, 0xad, 0xc4, + 0x77, 0xc5, 0xbe, 0xc6, 0xc7, 0xc8, 0x1d, 0xcb, 0x0e, 0xcd, 0x83, 0xce, + 0xf1, 0xcf, 0xb4, 0xd1, 0x7d, 0xd3, 0x86, 0xd5, 0x89, 0xd7, 0xd2, 0xd9, + 0x34, 0xdc, 0x28, 0xde, 0x23, 0xe0, 0x33, 0xe2, 0x0a, 0xe4, 0x59, 0xe5, + 0xfc, 0xe6, 0x98, 0xe9, 0x30, 0xec, 0x91, 0xee, 0xc2, 0xf0, 0x0d, 0xf3, + 0x35, 0xf5, 0xf3, 0xf6, 0xc4, 0xf8, 0xcb, 0xfa, 0xef, 0xfc, 0x65, 0xff, + 0x05, 0x02, 0x7c, 0x04, 0xde, 0x06, 0x75, 0x09, 0x2b, 0x0c, 0x9b, 0x0e, + 0xf3, 0x10, 0xb3, 0x13, 0x3a, 0x16, 0xeb, 0x18, 0x55, 0x1c, 0xad, 0x1f, + 0xa8, 0x22, 0x54, 0x25, 0xae, 0x27, 0x33, 0x2a, 0x16, 0x2d, 0x36, 0x30, + 0x84, 0x33, 0x94, 0x36, 0xbd, 0x38, 0xa2, 0x3a, 0x7d, 0x3c, 0x06, 0x3e, + 0x24, 0x3f, 0x27, 0x40, 0x7c, 0x41, 0xef, 0x42, 0x14, 0x44, 0xeb, 0x44, + 0x06, 0x46, 0x53, 0x47, 0x47, 0x48, 0x9b, 0x48, 0xaf, 0x48, 0xd7, 0x48, + 0x4c, 0x49, 0xa0, 0x49, 0xbe, 0x49, 0xd4, 0x49, 0xfa, 0x49, 0x5e, 0x4a, + 0xcc, 0x4a, 0x14, 0x4b, 0xfe, 0x4a, 0x22, 0x4b, 0x10, 0x4c, 0x0c, 0x4d, + 0xb2, 0x4d, 0x4c, 0x4e, 0x3e, 0x4e, 0x77, 0x4d, 0x98, 0x4c, 0xf6, 0x4b, + 0x67, 0x4b, 0xf0, 0x4a, 0x2a, 0x4a, 0xea, 0x48, 0x06, 0x48, 0x47, 0x47, + 0xb2, 0x46, 0xda, 0x45, 0xad, 0x44, 0x5c, 0x43, 0x43, 0x42, 0x9e, 0x41, + 0x0a, 0x41, 0x49, 0x40, 0xa6, 0x3f, 0x9d, 0x3e, 0x3c, 0x3d, 0xc6, 0x3b, + 0xf6, 0x39, 0x87, 0x37, 0xf6, 0x34, 0x87, 0x32, 0x2b, 0x30, 0x6f, 0x2d, + 0xfa, 0x2a, 0x3d, 0x29, 0x48, 0x27, 0xc2, 0x24, 0x49, 0x22, 0xca, 0x1f, + 0xa0, 0x1c, 0x7c, 0x19, 0x06, 0x17, 0xbf, 0x14, 0x9f, 0x12, 0x96, 0x10, + 0xf9, 0x0d, 0x3e, 0x0b, 0xe8, 0x08, 0x5c, 0x06, 0xe7, 0x02, 0x6e, 0xff, + 0xca, 0xfc, 0x5b, 0xfa, 0xa0, 0xf7, 0xe9, 0xf4, 0x9c, 0xf2, 0x66, 0xf0, + 0xaf, 0xed, 0xfd, 0xea, 0xcc, 0xe8, 0x6e, 0xe6, 0x82, 0xe3, 0x97, 0xe0, + 0xed, 0xdd, 0x62, 0xdb, 0x7b, 0xd8, 0xd3, 0xd5, 0x5f, 0xd3, 0x1a, 0xd1, + 0x44, 0xcf, 0xeb, 0xcd, 0x89, 0xcc, 0xca, 0xca, 0x4d, 0xc9, 0x35, 0xc8, + 0x53, 0xc7, 0x0c, 0xc6, 0x06, 0xc4, 0xca, 0xc1, 0x09, 0xc0, 0x9c, 0xbe, + 0xa8, 0xbd, 0xfd, 0xbc, 0xf2, 0xbb, 0x9b, 0xba, 0x20, 0xb9, 0xe4, 0xb7, + 0xc1, 0xb6, 0xcd, 0xb5, 0x12, 0xb5, 0x55, 0xb4, 0xd1, 0xb3, 0x86, 0xb3, + 0x19, 0xb3, 0xe8, 0xb2, 0xd7, 0xb2, 0x72, 0xb2, 0x27, 0xb2, 0xb7, 0xb1, + 0x67, 0xb1, 0x65, 0xb1, 0xae, 0xb1, 0x6b, 0xb1, 0xf2, 0xb0, 0xeb, 0xb0, + 0x0f, 0xb1, 0xfe, 0xb0, 0xeb, 0xb0, 0xcf, 0xb0, 0x94, 0xb0, 0x3e, 0xb0, + 0x29, 0xb0, 0x56, 0xb0, 0x0c, 0xb0, 0xb7, 0xaf, 0xfb, 0xaf, 0x37, 0xb0, + 0x96, 0xb0, 0x42, 0xb1, 0xe8, 0xb1, 0xb5, 0xb2, 0xc5, 0xb3, 0x93, 0xb4, + 0x93, 0xb4, 0xee, 0xb4, 0x59, 0xb6, 0xca, 0xb7, 0x87, 0xb8, 0x6f, 0xb8, + 0x33, 0xb8, 0xaf, 0xb8, 0x4a, 0xb9, 0x9d, 0xb9, 0xf2, 0xb9, 0x48, 0xba, + 0xd0, 0xba, 0xe5, 0xbb, 0x4e, 0xbd, 0xaf, 0xbe, 0xe9, 0xbf, 0xba, 0xc1, + 0xc2, 0xc3, 0x73, 0xc5, 0xa6, 0xc6, 0x6a, 0xc7, 0x83, 0xc8, 0x42, 0xca, + 0xc8, 0xcb, 0x34, 0xcd, 0x94, 0xce, 0xcc, 0xcf, 0x31, 0xd1, 0x27, 0xd3, + 0x8c, 0xd5, 0x61, 0xd7, 0x78, 0xd9, 0x3b, 0xdc, 0x40, 0xdf, 0xdd, 0xe1, + 0x0c, 0xe4, 0xe4, 0xe5, 0xd0, 0xe7, 0x65, 0xea, 0xc9, 0xec, 0xd7, 0xee, + 0xfc, 0xf0, 0x7c, 0xf3, 0xf6, 0xf5, 0x09, 0xf8, 0xde, 0xf9, 0xca, 0xfb, + 0xac, 0xfd, 0xc3, 0xff, 0x33, 0x02, 0xb1, 0x04, 0x24, 0x07, 0x57, 0x09, + 0x5f, 0x0b, 0xe6, 0x0d, 0xd1, 0x10, 0x6d, 0x13, 0x8f, 0x15, 0xfb, 0x17, + 0x43, 0x1a, 0x8e, 0x1c, 0x1a, 0x1f, 0x69, 0x21, 0x80, 0x23, 0x74, 0x25, + 0x62, 0x27, 0x07, 0x29, 0xa1, 0x2a, 0xa5, 0x2c, 0xdf, 0x2e, 0x57, 0x31, + 0xff, 0x33, 0xd1, 0x36, 0x6e, 0x39, 0x8a, 0x3b, 0x58, 0x3d, 0x32, 0x3f, + 0xc8, 0x40, 0x1b, 0x42, 0x22, 0x43, 0x1a, 0x44, 0x25, 0x45, 0xe5, 0x45, + 0x43, 0x46, 0x9b, 0x46, 0x6a, 0x47, 0x6f, 0x48, 0x69, 0x49, 0x6f, 0x4a, + 0xc7, 0x4b, 0x0e, 0x4d, 0x03, 0x4e, 0x78, 0x4e, 0xdf, 0x4e, 0x0b, 0x4f, + 0xea, 0x4e, 0xcb, 0x4e, 0x1b, 0x4f, 0x6e, 0x4f, 0xc3, 0x4f, 0xdc, 0x4f, + 0xcb, 0x4f, 0xd2, 0x4f, 0x16, 0x50, 0x24, 0x50, 0xf2, 0x4f, 0x00, 0x50, + 0x37, 0x50, 0x4e, 0x50, 0x5e, 0x50, 0x7c, 0x50, 0xab, 0x50, 0x69, 0x50, + 0xad, 0x4f, 0xa3, 0x4e, 0xe6, 0x4d, 0x42, 0x4d, 0xdc, 0x4c, 0x7c, 0x4c, + 0xbe, 0x4b, 0x08, 0x4b, 0x7b, 0x4a, 0xe4, 0x49, 0x14, 0x49, 0x07, 0x48, + 0x98, 0x46, 0x2f, 0x45, 0x16, 0x44, 0x23, 0x43, 0x55, 0x42, 0xac, 0x41, + 0x06, 0x41, 0x4b, 0x40, 0x8f, 0x3f, 0xde, 0x3e, 0xe1, 0x3d, 0x75, 0x3c, + 0xc0, 0x3a, 0xe4, 0x38, 0x83, 0x37, 0x9a, 0x36, 0xe5, 0x35, 0xc0, 0x34, + 0xf9, 0x32, 0xe1, 0x30, 0xfa, 0x2e, 0xd4, 0x2c, 0x4d, 0x2a, 0xed, 0x27, + 0xb9, 0x25, 0xb2, 0x23, 0x7d, 0x21, 0xfd, 0x1e, 0x89, 0x1c, 0x38, 0x1a, + 0xe2, 0x17, 0x67, 0x15, 0xf3, 0x12, 0xb3, 0x10, 0x9e, 0x0e, 0x79, 0x0c, + 0xea, 0x09, 0x54, 0x07, 0x26, 0x05, 0x0a, 0x03, 0xd7, 0x00, 0x98, 0xfe, + 0x41, 0xfc, 0x8d, 0xf9, 0x3c, 0xf7, 0x4f, 0xf5, 0x73, 0xf3, 0x7b, 0xf1, + 0x68, 0xef, 0x6f, 0xed, 0x7a, 0xeb, 0x87, 0xe9, 0x48, 0xe7, 0xc6, 0xe4, + 0x65, 0xe2, 0xf6, 0xdf, 0x86, 0xdd, 0x9f, 0xdb, 0x1b, 0xda, 0xa6, 0xd8, + 0xce, 0xd6, 0xe4, 0xd4, 0xe3, 0xd2, 0x84, 0xd0, 0xec, 0xcd, 0x08, 0xcc, + 0x89, 0xca, 0x1b, 0xc9, 0xe2, 0xc7, 0x9d, 0xc6, 0xe5, 0xc4, 0x79, 0xc3, + 0x6d, 0xc2, 0xe3, 0xc0, 0x3c, 0xbf, 0xd3, 0xbd, 0x41, 0xbc, 0xd2, 0xba, + 0x6a, 0xb9, 0xa1, 0xb7, 0xa9, 0xb5, 0x47, 0xb4, 0x91, 0xb3, 0xd5, 0xb2, + 0xb7, 0xb1, 0x51, 0xb0, 0x14, 0xaf, 0xf5, 0xad, 0x95, 0xac, 0x34, 0xab, + 0x05, 0xaa, 0xe1, 0xa8, 0xb3, 0xa7, 0xd9, 0xa6, 0x25, 0xa6, 0x6e, 0xa5, + 0x2b, 0xa5, 0x7b, 0xa5, 0x9a, 0xa5, 0x88, 0xa5, 0xc3, 0xa5, 0xe7, 0xa5, + 0xaf, 0xa5, 0x8b, 0xa5, 0x80, 0xa5, 0x65, 0xa5, 0x8c, 0xa5, 0x7e, 0xa5, + 0x22, 0xa5, 0x40, 0xa5, 0xed, 0xa5, 0x27, 0xa6, 0x2b, 0xa6, 0x1c, 0xa6, + 0xe5, 0xa5, 0x7b, 0xa5, 0x45, 0xa5, 0x37, 0xa5, 0x04, 0xa5, 0x91, 0xa4, + 0x8d, 0xa4, 0x2d, 0xa5, 0x9f, 0xa5, 0xf6, 0xa5, 0x7e, 0xa6, 0x34, 0xa7, + 0x14, 0xa8, 0x7e, 0xa8, 0x87, 0xa8, 0xc4, 0xa8, 0x51, 0xa9, 0xec, 0xa9, + 0x74, 0xaa, 0xf7, 0xaa, 0x40, 0xab, 0xd9, 0xab, 0xca, 0xac, 0x6b, 0xad, + 0xb3, 0xad, 0x08, 0xae, 0x10, 0xaf, 0x2c, 0xb0, 0xcb, 0xb0, 0x23, 0xb1, + 0xac, 0xb1, 0x0e, 0xb2, 0x42, 0xb2, 0xd7, 0xb2, 0xef, 0xb3, 0x21, 0xb5, + 0x30, 0xb6, 0xe9, 0xb6, 0x54, 0xb7, 0xf0, 0xb7, 0x9e, 0xb8, 0x2e, 0xb9, + 0x03, 0xba, 0x55, 0xbb, 0xdf, 0xbc, 0x5f, 0xbe, 0xb8, 0xbf, 0x01, 0xc1, + 0x83, 0xc2, 0x0c, 0xc4, 0x65, 0xc5, 0x7e, 0xc6, 0x86, 0xc7, 0xba, 0xc8, + 0x11, 0xca, 0x66, 0xcb, 0x28, 0xcd, 0x4d, 0xcf, 0x60, 0xd1, 0x69, 0xd3, + 0x7b, 0xd5, 0x5f, 0xd7, 0xe3, 0xd8, 0xca, 0xda, 0xda, 0xdc, 0xda, 0xde, + 0xab, 0xe0, 0x59, 0xe2, 0x3b, 0xe4, 0x21, 0xe6, 0xfc, 0xe7, 0xcb, 0xe9, + 0xbe, 0xeb, 0x9c, 0xed, 0x47, 0xef, 0x0b, 0xf1, 0xd3, 0xf2, 0xbc, 0xf4, + 0x9c, 0xf6, 0x67, 0xf8, 0x2a, 0xfa, 0xc1, 0xfb, 0x7f, 0xfd, 0x41, 0xff, + 0x12, 0x01, 0xd2, 0x02, 0xfc, 0x04, 0xe8, 0x06, 0x9a, 0x08, 0x59, 0x0a, + 0x48, 0x0c, 0x36, 0x0e, 0x37, 0x10, 0x36, 0x12, 0x59, 0x14, 0x62, 0x16, + 0x86, 0x18, 0xb9, 0x1a, 0xc2, 0x1c, 0xcd, 0x1e, 0xf1, 0x20, 0x27, 0x23, + 0x7a, 0x25, 0xf9, 0x27, 0x2a, 0x2a, 0x1f, 0x2c, 0xf8, 0x2d, 0xa3, 0x2f, + 0x23, 0x31, 0xf4, 0x32, 0x2c, 0x35, 0x40, 0x37, 0x23, 0x39, 0xfe, 0x3a, + 0x11, 0x3d, 0x2c, 0x3f, 0xe8, 0x40, 0x8c, 0x42, 0x55, 0x44, 0x37, 0x46, + 0x99, 0x47, 0xcb, 0x48, 0x12, 0x4a, 0x60, 0x4b, 0x86, 0x4c, 0x9b, 0x4d, + 0xc8, 0x4e, 0xec, 0x4f, 0xe3, 0x50, 0x8a, 0x51, 0x23, 0x52, 0xd8, 0x52, + 0x68, 0x53, 0x9b, 0x53, 0xb1, 0x53, 0x11, 0x54, 0x94, 0x54, 0xf7, 0x54, + 0x4f, 0x55, 0xa4, 0x55, 0x03, 0x56, 0x51, 0x56, 0x92, 0x56, 0xfa, 0x56, + 0x59, 0x57, 0xad, 0x57, 0xcd, 0x57, 0xc5, 0x57, 0xa8, 0x57, 0x64, 0x57, + 0x49, 0x57, 0x63, 0x57, 0x64, 0x57, 0x40, 0x57, 0xf6, 0x56, 0xfc, 0x56, + 0x36, 0x57, 0x3b, 0x57, 0x1e, 0x57, 0x1c, 0x57, 0x03, 0x57, 0xee, 0x56, + 0xa5, 0x56, 0x80, 0x56, 0xd4, 0x56, 0xe4, 0x56, 0x92, 0x56, 0xf0, 0x55, + 0x02, 0x55, 0xab, 0x53, 0xb5, 0x52, 0x51, 0x52, 0x08, 0x52, 0x80, 0x51, + 0xb4, 0x50, 0xde, 0x4f, 0x27, 0x4f, 0x63, 0x4e, 0x58, 0x4d, 0x72, 0x4c, + 0x82, 0x4b, 0x81, 0x4a, 0x87, 0x49, 0xb4, 0x48, 0xb1, 0x47, 0x99, 0x46, + 0xb4, 0x45, 0x34, 0x45, 0xb8, 0x44, 0x2f, 0x44, 0x7f, 0x43, 0xa0, 0x42, + 0xcb, 0x41, 0xd1, 0x40, 0xeb, 0x3f, 0x28, 0x3f, 0x3d, 0x3e, 0x09, 0x3d, + 0x9d, 0x3b, 0x40, 0x3a, 0x1c, 0x39, 0xeb, 0x37, 0xd1, 0x36, 0xb3, 0x35, + 0x8b, 0x34, 0x0b, 0x33, 0x51, 0x31, 0xfb, 0x2f, 0xb9, 0x2e, 0x54, 0x2d, + 0xaf, 0x2b, 0xdf, 0x29, 0xf1, 0x27, 0x3a, 0x26, 0x6f, 0x24, 0x56, 0x22, + 0x20, 0x20, 0x0a, 0x1e, 0x3b, 0x1c, 0x55, 0x1a, 0x6c, 0x18, 0xaa, 0x16, + 0xef, 0x14, 0x0a, 0x13, 0x17, 0x11, 0x1c, 0x0f, 0x22, 0x0d, 0x46, 0x0b, + 0x53, 0x09, 0x46, 0x07, 0x46, 0x05, 0x4d, 0x03, 0x1a, 0x01, 0xd3, 0xfe, + 0x94, 0xfc, 0x8c, 0xfa, 0x8f, 0xf8, 0xc1, 0xf6, 0x27, 0xf5, 0x8f, 0xf3, + 0xf2, 0xf1, 0x74, 0xf0, 0xfa, 0xee, 0x4d, 0xed, 0x9e, 0xeb, 0xa2, 0xe9, + 0x73, 0xe7, 0xa9, 0xe5, 0x2d, 0xe4, 0xa3, 0xe2, 0xf9, 0xe0, 0x50, 0xdf, + 0xb9, 0xdd, 0x34, 0xdc, 0xad, 0xda, 0x0b, 0xd9, 0x77, 0xd7, 0xb9, 0xd5, + 0x37, 0xd4, 0xff, 0xd2, 0x8a, 0xd1, 0x14, 0xd0, 0xba, 0xce, 0x7d, 0xcd, + 0x2c, 0xcc, 0xa1, 0xca, 0x22, 0xc9, 0xa9, 0xc7, 0x0e, 0xc6, 0x66, 0xc4, + 0xfc, 0xc2, 0xa5, 0xc1, 0x4a, 0xc0, 0xff, 0xbe, 0xf7, 0xbd, 0x0e, 0xbd, + 0x1d, 0xbc, 0x16, 0xbb, 0xad, 0xb9, 0x44, 0xb8, 0xd7, 0xb6, 0x9e, 0xb5, + 0x9f, 0xb4, 0x97, 0xb3, 0x72, 0xb2, 0x5f, 0xb1, 0x67, 0xb0, 0x89, 0xaf, + 0x9d, 0xae, 0xbe, 0xad, 0x08, 0xad, 0x5d, 0xac, 0x8b, 0xab, 0xad, 0xaa, + 0xe4, 0xa9, 0x59, 0xa9, 0xc4, 0xa8, 0x02, 0xa8, 0x4d, 0xa7, 0xc2, 0xa6, + 0x4a, 0xa6, 0x09, 0xa6, 0xd2, 0xa5, 0x50, 0xa5, 0xec, 0xa4, 0xc2, 0xa4, + 0xd9, 0xa4, 0xbd, 0xa4, 0x97, 0xa4, 0xa5, 0xa4, 0xbf, 0xa4, 0xb4, 0xa4, + 0x8f, 0xa4, 0x31, 0xa4, 0x39, 0xa4, 0x7d, 0xa4, 0xab, 0xa4, 0xc7, 0xa4, + 0xb3, 0xa4, 0xab, 0xa4, 0xca, 0xa4, 0x05, 0xa5, 0x1e, 0xa5, 0x2a, 0xa5, + 0x2c, 0xa5, 0x18, 0xa5, 0x01, 0xa5, 0x33, 0xa5, 0x8c, 0xa5, 0xb2, 0xa5, + 0x81, 0xa5, 0x5c, 0xa5, 0x6e, 0xa5, 0x79, 0xa5, 0x4e, 0xa5, 0x17, 0xa5, + 0xff, 0xa4, 0x1c, 0xa5, 0x45, 0xa5, 0x8a, 0xa5, 0xbf, 0xa5, 0xdb, 0xa5, + 0x41, 0xa6, 0xfb, 0xa6, 0xc6, 0xa7, 0x86, 0xa8, 0x29, 0xa9, 0x97, 0xa9, + 0x27, 0xaa, 0xd7, 0xaa, 0x6d, 0xab, 0xf4, 0xab, 0x34, 0xac, 0x69, 0xac, + 0xc6, 0xac, 0x37, 0xad, 0xaa, 0xad, 0x34, 0xae, 0xd3, 0xae, 0x81, 0xaf, + 0x16, 0xb0, 0x72, 0xb0, 0xc8, 0xb0, 0x36, 0xb1, 0x91, 0xb1, 0xe0, 0xb1, + 0x3b, 0xb2, 0x8e, 0xb2, 0xe0, 0xb2, 0x2a, 0xb3, 0xab, 0xb3, 0x3a, 0xb4, + 0xf1, 0xb4, 0xc0, 0xb5, 0xae, 0xb6, 0x91, 0xb7, 0x82, 0xb8, 0x98, 0xb9, + 0x8f, 0xba, 0x88, 0xbb, 0x65, 0xbc, 0x20, 0xbd, 0xcb, 0xbd, 0xaf, 0xbe, + 0x94, 0xbf, 0x84, 0xc0, 0x85, 0xc1, 0x7b, 0xc2, 0x67, 0xc3, 0x66, 0xc4, + 0x7f, 0xc5, 0x89, 0xc6, 0x6b, 0xc7, 0x38, 0xc8, 0x29, 0xc9, 0x4a, 0xca, + 0x82, 0xcb, 0xc1, 0xcc, 0x12, 0xce, 0x5e, 0xcf, 0xb0, 0xd0, 0x25, 0xd2, + 0x66, 0xd3, 0xde, 0xd4, 0x6c, 0xd6, 0x28, 0xd8, 0xd7, 0xd9, 0x80, 0xdb, + 0xf7, 0xdc, 0x6f, 0xde, 0xd0, 0xdf, 0x22, 0xe1, 0x7a, 0xe2, 0xe5, 0xe3, + 0x7a, 0xe5, 0xea, 0xe6, 0x51, 0xe8, 0xeb, 0xe9, 0x70, 0xeb, 0xb3, 0xec, + 0x01, 0xee, 0x60, 0xef, 0xcb, 0xf0, 0x1d, 0xf2, 0x7b, 0xf3, 0xcf, 0xf4, + 0x39, 0xf6, 0xc8, 0xf7, 0x82, 0xf9, 0x4a, 0xfb, 0xf2, 0xfc, 0x8c, 0xfe, + 0x01, 0x00, 0x68, 0x01, 0x15, 0x03, 0xe6, 0x04, 0xbc, 0x06, 0x42, 0x08, + 0xbb, 0x09, 0x2b, 0x0b, 0xc7, 0x0c, 0x35, 0x0e, 0x94, 0x0f, 0xf2, 0x10, + 0x59, 0x12, 0xbc, 0x13, 0x34, 0x15, 0xac, 0x16, 0x1c, 0x18, 0x79, 0x19, + 0xdc, 0x1a, 0x6d, 0x1c, 0x21, 0x1e, 0xca, 0x1f, 0x70, 0x21, 0x02, 0x23, + 0x6c, 0x24, 0x9e, 0x25, 0x45, 0x27, 0x02, 0x29, 0x95, 0x2a, 0xff, 0x2b, + 0x72, 0x2d, 0xe8, 0x2e, 0x48, 0x30, 0x7c, 0x31, 0xd2, 0x32, 0x3d, 0x34, + 0xac, 0x35, 0x26, 0x37, 0xbc, 0x38, 0x4c, 0x3a, 0x90, 0x3b, 0xef, 0x3c, + 0x61, 0x3e, 0xe8, 0x3f, 0x59, 0x41, 0xab, 0x42, 0xf7, 0x43, 0x2d, 0x45, + 0x6c, 0x46, 0x78, 0x47, 0xb4, 0x48, 0x2e, 0x4a, 0x8e, 0x4b, 0xd7, 0x4c, + 0xf4, 0x4d, 0xee, 0x4e, 0xcb, 0x4f, 0xc3, 0x50, 0xc2, 0x51, 0xac, 0x52, + 0x61, 0x53, 0xf3, 0x53, 0xac, 0x54, 0x5f, 0x55, 0xf4, 0x55, 0x7f, 0x56, + 0x04, 0x57, 0x9c, 0x57, 0x1f, 0x58, 0x7c, 0x58, 0xbc, 0x58, 0x0b, 0x59, + 0x71, 0x59, 0xc1, 0x59, 0x0b, 0x5a, 0x3e, 0x5a, 0x8b, 0x5a, 0xac, 0x5a, + 0xa9, 0x5a, 0x8a, 0x5a, 0x6c, 0x5a, 0x4c, 0x5a, 0x39, 0x5a, 0x32, 0x5a, + 0x40, 0x5a, 0x33, 0x5a, 0x44, 0x5a, 0x58, 0x5a, 0x79, 0x5a, 0x7a, 0x5a, + 0x69, 0x5a, 0x49, 0x5a, 0x54, 0x5a, 0x78, 0x5a, 0x72, 0x5a, 0x5f, 0x5a, + 0x31, 0x5a, 0x11, 0x5a, 0xf9, 0x59, 0xea, 0x59, 0xd1, 0x59, 0xa1, 0x59, + 0x48, 0x59, 0xf0, 0x58, 0xa2, 0x58, 0x6e, 0x58, 0x60, 0x58, 0x46, 0x58, + 0x3f, 0x58, 0x47, 0x58, 0x40, 0x58, 0x08, 0x58, 0x9c, 0x57, 0x11, 0x57, + 0x83, 0x56, 0xd7, 0x55, 0x42, 0x55, 0xab, 0x54, 0x06, 0x54, 0x63, 0x53, + 0xa6, 0x52, 0xf0, 0x51, 0x55, 0x51, 0xbc, 0x50, 0x1e, 0x50, 0x8e, 0x4f, + 0xf3, 0x4e, 0x34, 0x4e, 0x6b, 0x4d, 0xc9, 0x4c, 0x30, 0x4c, 0x7d, 0x4b, + 0xd8, 0x4a, 0x49, 0x4a, 0xad, 0x49, 0x11, 0x49, 0x6c, 0x48, 0xa4, 0x47, + 0xec, 0x46, 0x6c, 0x46, 0xde, 0x45, 0x5d, 0x45, 0xbc, 0x44, 0xf1, 0x43, + 0x34, 0x43, 0x8c, 0x42, 0xf8, 0x41, 0x47, 0x41, 0x6a, 0x40, 0x72, 0x3f, + 0x8b, 0x3e, 0xb3, 0x3d, 0xf2, 0x3c, 0x2f, 0x3c, 0x5c, 0x3b, 0x96, 0x3a, + 0xbc, 0x39, 0xb2, 0x38, 0x91, 0x37, 0x8c, 0x36, 0x75, 0x35, 0x63, 0x34, + 0x5e, 0x33, 0x63, 0x32, 0x4b, 0x31, 0x3c, 0x30, 0x1e, 0x2f, 0x07, 0x2e, + 0xd0, 0x2c, 0xb2, 0x2b, 0x84, 0x2a, 0x4d, 0x29, 0xfc, 0x27, 0xa5, 0x26, + 0x2f, 0x25, 0x95, 0x23, 0x1f, 0x22, 0xad, 0x20, 0x3a, 0x1f, 0x9e, 0x1d, + 0x10, 0x1c, 0x6e, 0x1a, 0xe3, 0x18, 0x56, 0x17, 0xdb, 0x15, 0x58, 0x14, + 0xba, 0x12, 0x2a, 0x11, 0x8b, 0x0f, 0xf4, 0x0d, 0x5b, 0x0c, 0xd3, 0x0a, + 0x5f, 0x09, 0xe5, 0x07, 0x4a, 0x06, 0xc0, 0x04, 0x3e, 0x03, 0xb6, 0x01, + 0x37, 0x00, 0xca, 0xfe, 0x74, 0xfd, 0x00, 0xfc, 0xa5, 0xfa, 0x4a, 0xf9, + 0xd1, 0xf7, 0x7e, 0xf6, 0x1c, 0xf5, 0x9d, 0xf3, 0x4f, 0xf2, 0x0e, 0xf1, + 0xc0, 0xef, 0x3a, 0xee, 0xd8, 0xec, 0x69, 0xeb, 0x0c, 0xea, 0xad, 0xe8, + 0x56, 0xe7, 0xf8, 0xe5, 0xbe, 0xe4, 0x98, 0xe3, 0x61, 0xe2, 0x03, 0xe1, + 0x99, 0xdf, 0x4d, 0xde, 0x0e, 0xdd, 0xde, 0xdb, 0xad, 0xda, 0x84, 0xd9, + 0x62, 0xd8, 0x32, 0xd7, 0x01, 0xd6, 0xb7, 0xd4, 0x87, 0xd3, 0x97, 0xd2, + 0x89, 0xd1, 0x89, 0xd0, 0x6e, 0xcf, 0x65, 0xce, 0x5d, 0xcd, 0x44, 0xcc, + 0x13, 0xcb, 0xf2, 0xc9, 0xd3, 0xc8, 0xad, 0xc7, 0x9b, 0xc6, 0x94, 0xc5, + 0x8e, 0xc4, 0x7b, 0xc3, 0x92, 0xc2, 0xad, 0xc1, 0xb2, 0xc0, 0xb9, 0xbf, + 0xb3, 0xbe, 0xc0, 0xbd, 0xd5, 0xbc, 0xf2, 0xbb, 0xe1, 0xba, 0xc7, 0xb9, + 0xc7, 0xb8, 0xe8, 0xb7, 0x09, 0xb7, 0x2c, 0xb6, 0x66, 0xb5, 0xb1, 0xb4, + 0xf6, 0xb3, 0x32, 0xb3, 0x53, 0xb2, 0x92, 0xb1, 0xdb, 0xb0, 0x0d, 0xb0, + 0x46, 0xaf, 0x62, 0xae, 0x98, 0xad, 0xd1, 0xac, 0x3f, 0xac, 0xb0, 0xab, + 0x34, 0xab, 0xb1, 0xaa, 0x45, 0xaa, 0xda, 0xa9, 0x6a, 0xa9, 0xf1, 0xa8, + 0x7d, 0xa8, 0x04, 0xa8, 0xbb, 0xa7, 0x80, 0xa7, 0x41, 0xa7, 0x02, 0xa7, + 0xb6, 0xa6, 0x68, 0xa6, 0x3b, 0xa6, 0x1c, 0xa6, 0x0d, 0xa6, 0xfc, 0xa5, + 0xd4, 0xa5, 0xa6, 0xa5, 0x81, 0xa5, 0x76, 0xa5, 0x61, 0xa5, 0x54, 0xa5, + 0x48, 0xa5, 0x47, 0xa5, 0x4b, 0xa5, 0x49, 0xa5, 0x38, 0xa5, 0x4b, 0xa5, + 0x6c, 0xa5, 0xa3, 0xa5, 0xda, 0xa5, 0xfe, 0xa5, 0x21, 0xa6, 0x4a, 0xa6, + 0x8a, 0xa6, 0xb4, 0xa6, 0xe0, 0xa6, 0xf3, 0xa6, 0x1b, 0xa7, 0x17, 0xa7, + 0x40, 0xa7, 0x8e, 0xa7, 0xcd, 0xa7, 0x06, 0xa8, 0x3e, 0xa8, 0x86, 0xa8, + 0xbd, 0xa8, 0xde, 0xa8, 0xf6, 0xa8, 0x1c, 0xa9, 0x49, 0xa9, 0x5c, 0xa9, + 0x79, 0xa9, 0x93, 0xa9, 0xab, 0xa9, 0xe6, 0xa9, 0x2c, 0xaa, 0x82, 0xaa, + 0xbc, 0xaa, 0xec, 0xaa, 0x32, 0xab, 0x69, 0xab, 0xa7, 0xab, 0xde, 0xab, + 0x19, 0xac, 0x53, 0xac, 0xbb, 0xac, 0x14, 0xad, 0x8a, 0xad, 0xeb, 0xad, + 0x6c, 0xae, 0xe1, 0xae, 0x62, 0xaf, 0xd9, 0xaf, 0x58, 0xb0, 0xc0, 0xb0, + 0x36, 0xb1, 0x99, 0xb1, 0x11, 0xb2, 0x71, 0xb2, 0xdc, 0xb2, 0x58, 0xb3, + 0xbb, 0xb3, 0x37, 0xb4, 0xb6, 0xb4, 0x46, 0xb5, 0xca, 0xb5, 0x50, 0xb6, + 0xd9, 0xb6, 0x6c, 0xb7, 0x03, 0xb8, 0x7e, 0xb8, 0xf0, 0xb8, 0x64, 0xb9, + 0xcf, 0xb9, 0x47, 0xba, 0xd3, 0xba, 0x60, 0xbb, 0xe8, 0xbb, 0x70, 0xbc, + 0xf3, 0xbc, 0x82, 0xbd, 0x05, 0xbe, 0xa1, 0xbe, 0x2a, 0xbf, 0xae, 0xbf, + 0x25, 0xc0, 0xac, 0xc0, 0x52, 0xc1, 0xde, 0xc1, 0x75, 0xc2, 0x11, 0xc3, + 0xb5, 0xc3, 0x42, 0xc4, 0xc5, 0xc4, 0x6d, 0xc5, 0x0b, 0xc6, 0xb2, 0xc6, + 0x4b, 0xc7, 0xf6, 0xc7, 0x9b, 0xc8, 0x4f, 0xc9, 0x17, 0xca, 0xf3, 0xca, + 0xc6, 0xcb, 0x9a, 0xcc, 0x7b, 0xcd, 0x54, 0xce, 0x32, 0xcf, 0x09, 0xd0, + 0xd7, 0xd0, 0xc9, 0xd1, 0xc1, 0xd2, 0xb8, 0xd3, 0xb6, 0xd4, 0xae, 0xd5, + 0xbc, 0xd6, 0xca, 0xd7, 0xd2, 0xd8, 0xca, 0xd9, 0xbd, 0xda, 0xc8, 0xdb, + 0xd8, 0xdc, 0xf9, 0xdd, 0x08, 0xdf, 0x1e, 0xe0, 0x39, 0xe1, 0x4e, 0xe2, + 0x60, 0xe3, 0x7a, 0xe4, 0x96, 0xe5, 0xc1, 0xe6, 0xde, 0xe7, 0x0e, 0xe9, + 0x2a, 0xea, 0x42, 0xeb, 0x7a, 0xec, 0x9f, 0xed, 0xbb, 0xee, 0xd6, 0xef, + 0xef, 0xf0, 0x0e, 0xf2, 0x30, 0xf3, 0x55, 0xf4, 0x68, 0xf5, 0x7e, 0xf6, + 0xa4, 0xf7, 0xc0, 0xf8, 0xea, 0xf9, 0x10, 0xfb, 0x41, 0xfc, 0x7d, 0xfd, + 0xad, 0xfe, 0xe3, 0xff, 0x10, 0x01, 0x27, 0x02, 0x58, 0x03, 0x74, 0x04, + 0xa4, 0x05, 0xd5, 0x06, 0x0b, 0x08, 0x36, 0x09, 0x5c, 0x0a, 0x76, 0x0b, + 0x9a, 0x0c, 0xc1, 0x0d, 0xd8, 0x0e, 0xf5, 0x0f, 0x15, 0x11, 0x3f, 0x12, + 0x70, 0x13, 0x8e, 0x14, 0xcc, 0x15, 0xf2, 0x16, 0x31, 0x18, 0x4b, 0x19, + 0x82, 0x1a, 0xa1, 0x1b, 0xbc, 0x1c, 0xde, 0x1d, 0xe9, 0x1e, 0x13, 0x20, + 0x33, 0x21, 0x6c, 0x22, 0x80, 0x23, 0xa7, 0x24, 0xbc, 0x25, 0xde, 0x26, + 0xe7, 0x27, 0x07, 0x29, 0x28, 0x2a, 0x36, 0x2b, 0x4d, 0x2c, 0x71, 0x2d, + 0x91, 0x2e, 0xbe, 0x2f, 0xd6, 0x30, 0xfb, 0x31, 0x20, 0x33, 0x46, 0x34, + 0x59, 0x35, 0x7a, 0x36, 0xa1, 0x37, 0xc2, 0x38, 0xdf, 0x39, 0x01, 0x3b, + 0x0f, 0x3c, 0x27, 0x3d, 0x1f, 0x3e, 0x2e, 0x3f, 0x43, 0x40, 0x5b, 0x41, + 0x73, 0x42, 0x8e, 0x43, 0xaf, 0x44, 0xbc, 0x45, 0xcc, 0x46, 0xd8, 0x47, + 0xec, 0x48, 0xe1, 0x49, 0xd1, 0x4a, 0xc4, 0x4b, 0xb6, 0x4c, 0xa9, 0x4d, + 0x9d, 0x4e, 0x88, 0x4f, 0x75, 0x50, 0x4c, 0x51, 0x3b, 0x52, 0x05, 0x53, + 0xd9, 0x53, 0xa1, 0x54, 0x6f, 0x55, 0x33, 0x56, 0xe5, 0x56, 0x7d, 0x57, + 0x15, 0x58, 0xb3, 0x58, 0x4e, 0x59, 0xdb, 0x59, 0x55, 0x5a, 0xc8, 0x5a, + 0x36, 0x5b, 0xa9, 0x5b, 0x09, 0x5c, 0x5a, 0x5c, 0xab, 0x5c, 0xf1, 0x5c, + 0x34, 0x5d, 0x6a, 0x5d, 0x9e, 0x5d, 0xc1, 0x5d, 0xea, 0x5d, 0x0b, 0x5e, + 0x28, 0x5e, 0x3d, 0x5e, 0x41, 0x5e, 0x51, 0x5e, 0x5f, 0x5e, 0x69, 0x5e, + 0x79, 0x5e, 0x6a, 0x5e, 0x78, 0x5e, 0x76, 0x5e, 0x7f, 0x5e, 0x72, 0x5e, + 0x70, 0x5e, 0x61, 0x5e, 0x61, 0x5e, 0x42, 0x5e, 0x36, 0x5e, 0x2f, 0x5e, + 0x2c, 0x5e, 0x1a, 0x5e, 0xec, 0x5d, 0xbf, 0x5d, 0x94, 0x5d, 0x71, 0x5d, + 0x4c, 0x5d, 0x24, 0x5d, 0xfa, 0x5c, 0xc3, 0x5c, 0x8c, 0x5c, 0x59, 0x5c, + 0x3e, 0x5c, 0x0c, 0x5c, 0xd3, 0x5b, 0xb1, 0x5b, 0x78, 0x5b, 0x45, 0x5b, + 0x14, 0x5b, 0xed, 0x5a, 0xc0, 0x5a, 0x89, 0x5a, 0x4f, 0x5a, 0x16, 0x5a, + 0xe5, 0x59, 0xb5, 0x59, 0x84, 0x59, 0x4e, 0x59, 0x0d, 0x59, 0xcf, 0x58, + 0xa6, 0x58, 0x79, 0x58, 0x3e, 0x58, 0xf8, 0x57, 0xc0, 0x57, 0x83, 0x57, + 0x38, 0x57, 0x03, 0x57, 0xc1, 0x56, 0x65, 0x56, 0xe0, 0x55, 0x52, 0x55, + 0xd0, 0x54, 0x4c, 0x54, 0xbe, 0x53, 0x32, 0x53, 0xa7, 0x52, 0x2a, 0x52, + 0x95, 0x51, 0x09, 0x51, 0x76, 0x50, 0xe9, 0x4f, 0x69, 0x4f, 0xe2, 0x4e, + 0x49, 0x4e, 0xc0, 0x4d, 0x38, 0x4d, 0xbd, 0x4c, 0x2d, 0x4c, 0x98, 0x4b, + 0x07, 0x4b, 0x76, 0x4a, 0xdc, 0x49, 0x4a, 0x49, 0xb9, 0x48, 0x2d, 0x48, + 0x9c, 0x47, 0x19, 0x47, 0x80, 0x46, 0xf9, 0x45, 0x66, 0x45, 0xd6, 0x44, + 0x47, 0x44, 0xb5, 0x43, 0x14, 0x43, 0x74, 0x42, 0xd4, 0x41, 0x42, 0x41, + 0xa4, 0x40, 0x18, 0x40, 0x85, 0x3f, 0xeb, 0x3e, 0x52, 0x3e, 0xb2, 0x3d, + 0x0c, 0x3d, 0x7a, 0x3c, 0xdb, 0x3b, 0x3a, 0x3b, 0x87, 0x3a, 0xe0, 0x39, + 0x29, 0x39, 0x88, 0x38, 0xd1, 0x37, 0x16, 0x37, 0x4d, 0x36, 0x9e, 0x35, + 0xdc, 0x34, 0x19, 0x34, 0x4a, 0x33, 0x83, 0x32, 0xb7, 0x31, 0xec, 0x30, + 0x1c, 0x30, 0x47, 0x2f, 0x71, 0x2e, 0x88, 0x2d, 0xa6, 0x2c, 0xbb, 0x2b, + 0xd0, 0x2a, 0xd8, 0x29, 0xdb, 0x28, 0xe3, 0x27, 0xf5, 0x26, 0xf1, 0x25, + 0xf8, 0x24, 0xdc, 0x23, 0xdb, 0x22, 0xca, 0x21, 0xa7, 0x20, 0x85, 0x1f, + 0x5a, 0x1e, 0x30, 0x1d, 0x0a, 0x1c, 0xd5, 0x1a, 0xa6, 0x19, 0x6d, 0x18, + 0x3d, 0x17, 0xff, 0x15, 0xbf, 0x14, 0x81, 0x13, 0x57, 0x12, 0x15, 0x11, + 0xe0, 0x0f, 0xa2, 0x0e, 0x65, 0x0d, 0x27, 0x0c, 0xf1, 0x0a, 0xb2, 0x09, + 0x77, 0x08, 0x4b, 0x07, 0x0a, 0x06, 0xc9, 0x04, 0x97, 0x03, 0x65, 0x02, + 0x3b, 0x01, 0x03, 0x00, 0xd2, 0xfe, 0x95, 0xfd, 0x6f, 0xfc, 0x50, 0xfb, + 0x19, 0xfa, 0xf0, 0xf8, 0xb8, 0xf7, 0x97, 0xf6, 0x65, 0xf5, 0x48, 0xf4, + 0x24, 0xf3, 0xfe, 0xf1, 0xec, 0xf0, 0xd2, 0xef, 0xa9, 0xee, 0x95, 0xed, + 0x76, 0xec, 0x64, 0xeb, 0x61, 0xea, 0x43, 0xe9, 0x3a, 0xe8, 0x21, 0xe7, + 0x14, 0xe6, 0xff, 0xe4, 0x06, 0xe4, 0x04, 0xe3, 0x04, 0xe2, 0x01, 0xe1, + 0x02, 0xe0, 0x04, 0xdf, 0x16, 0xde, 0x1f, 0xdd, 0x29, 0xdc, 0x2d, 0xdb, + 0x3d, 0xda, 0x45, 0xd9, 0x5a, 0xd8, 0x6f, 0xd7, 0x74, 0xd6, 0x8a, 0xd5, + 0x91, 0xd4, 0xa5, 0xd3, 0xbb, 0xd2, 0xdb, 0xd1, 0x01, 0xd1, 0x17, 0xd0, + 0x42, 0xcf, 0x5e, 0xce, 0x94, 0xcd, 0xb1, 0xcc, 0xe8, 0xcb, 0x04, 0xcb, + 0x29, 0xca, 0x4e, 0xc9, 0x78, 0xc8, 0x99, 0xc7, 0xc4, 0xc6, 0xff, 0xc5, + 0x3d, 0xc5, 0x76, 0xc4, 0xa6, 0xc3, 0xe4, 0xc2, 0x17, 0xc2, 0x4e, 0xc1, + 0x8a, 0xc0, 0xc5, 0xbf, 0x0b, 0xbf, 0x42, 0xbe, 0x8e, 0xbd, 0xd8, 0xbc, + 0x20, 0xbc, 0x60, 0xbb, 0xbb, 0xba, 0x08, 0xba, 0x5a, 0xb9, 0xba, 0xb8, + 0x08, 0xb8, 0x64, 0xb7, 0xb1, 0xb6, 0x0c, 0xb6, 0x5d, 0xb5, 0xbf, 0xb4, + 0x10, 0xb4, 0x7b, 0xb3, 0xd0, 0xb2, 0x3d, 0xb2, 0xa1, 0xb1, 0x0f, 0xb1, + 0x84, 0xb0, 0xf2, 0xaf, 0x63, 0xaf, 0xd3, 0xae, 0x50, 0xae, 0xbd, 0xad, + 0x49, 0xad, 0xc1, 0xac, 0x4d, 0xac, 0xc6, 0xab, 0x56, 0xab, 0xe4, 0xaa, + 0x83, 0xaa, 0x0d, 0xaa, 0xac, 0xa9, 0x49, 0xa9, 0xf3, 0xa8, 0x9e, 0xa8, + 0x4e, 0xa8, 0x07, 0xa8, 0xc5, 0xa7, 0x8d, 0xa7, 0x56, 0xa7, 0x1d, 0xa7, + 0xf6, 0xa6, 0xc7, 0xa6, 0xad, 0xa6, 0x8c, 0xa6, 0x74, 0xa6, 0x58, 0xa6, + 0x47, 0xa6, 0x2d, 0xa6, 0x24, 0xa6, 0x23, 0xa6, 0x21, 0xa6, 0x19, 0xa6, + 0x20, 0xa6, 0x1f, 0xa6, 0x28, 0xa6, 0x3c, 0xa6, 0x4e, 0xa6, 0x59, 0xa6, + 0x6e, 0xa6, 0x84, 0xa6, 0x9a, 0xa6, 0xb7, 0xa6, 0xd4, 0xa6, 0xef, 0xa6, + 0x0a, 0xa7, 0x2f, 0xa7, 0x53, 0xa7, 0x77, 0xa7, 0x9c, 0xa7, 0xbc, 0xa7, + 0xe5, 0xa7, 0x10, 0xa8, 0x35, 0xa8, 0x6d, 0xa8, 0x9b, 0xa8, 0xcb, 0xa8, + 0xf5, 0xa8, 0x23, 0xa9, 0x5a, 0xa9, 0x80, 0xa9, 0xb7, 0xa9, 0xee, 0xa9, + 0x1c, 0xaa, 0x46, 0xaa, 0x78, 0xaa, 0xb2, 0xaa, 0xeb, 0xaa, 0x1a, 0xab, + 0x57, 0xab, 0x84, 0xab, 0xba, 0xab, 0xef, 0xab, 0x22, 0xac, 0x55, 0xac, + 0x88, 0xac, 0xc1, 0xac, 0xf5, 0xac, 0x2a, 0xad, 0x67, 0xad, 0x9f, 0xad, + 0xe0, 0xad, 0x14, 0xae, 0x4c, 0xae, 0x82, 0xae, 0xb8, 0xae, 0xf8, 0xae, + 0x2c, 0xaf, 0x6a, 0xaf, 0x9d, 0xaf, 0xd4, 0xaf, 0x05, 0xb0, 0x38, 0xb0, + 0x77, 0xb0, 0xb2, 0xb0, 0xf8, 0xb0, 0x3c, 0xb1, 0x97, 0xb1, 0x05, 0xb2, + 0x6f, 0xb2, 0xdf, 0xb2, 0x48, 0xb3, 0xb2, 0xb3, 0x16, 0xb4, 0x7b, 0xb4, + 0xe5, 0xb4, 0x54, 0xb5, 0xc3, 0xb5, 0x26, 0xb6, 0x97, 0xb6, 0x03, 0xb7, + 0x68, 0xb7, 0xce, 0xb7, 0x44, 0xb8, 0xae, 0xb8, 0x20, 0xb9, 0x87, 0xb9, + 0xf1, 0xb9, 0x5d, 0xba, 0xc6, 0xba, 0x24, 0xbb, 0xa1, 0xbb, 0x05, 0xbc, + 0x79, 0xbc, 0xdc, 0xbc, 0x4b, 0xbd, 0xba, 0xbd, 0x24, 0xbe, 0x9b, 0xbe, + 0x07, 0xbf, 0x72, 0xbf, 0xe5, 0xbf, 0x46, 0xc0, 0xc3, 0xc0, 0x1f, 0xc1, + 0x91, 0xc1, 0x01, 0xc2, 0x79, 0xc2, 0xf1, 0xc2, 0x66, 0xc3, 0xe5, 0xc3, + 0x55, 0xc4, 0xc8, 0xc4, 0x3e, 0xc5, 0xb3, 0xc5, 0x2d, 0xc6, 0xa7, 0xc6, + 0x27, 0xc7, 0x97, 0xc7, 0x1f, 0xc8, 0xa0, 0xc8, 0x29, 0xc9, 0xad, 0xc9, + 0x36, 0xca, 0xad, 0xca, 0x3d, 0xcb, 0xc0, 0xcb, 0x47, 0xcc, 0xe9, 0xcc, + 0x6f, 0xcd, 0x06, 0xce, 0x84, 0xce, 0x1a, 0xcf, 0xbb, 0xcf, 0x55, 0xd0, + 0xf6, 0xd0, 0x8b, 0xd1, 0x30, 0xd2, 0xd2, 0xd2, 0x79, 0xd3, 0x1c, 0xd4, + 0xcf, 0xd4, 0x83, 0xd5, 0x36, 0xd6, 0xe1, 0xd6, 0x96, 0xd7, 0x5f, 0xd8, + 0x1c, 0xd9, 0xe2, 0xd9, 0xa8, 0xda, 0x6c, 0xdb, 0x43, 0xdc, 0x04, 0xdd, + 0xd8, 0xdd, 0xac, 0xde, 0x8a, 0xdf, 0x5b, 0xe0, 0x39, 0xe1, 0x0b, 0xe2, + 0xf5, 0xe2, 0xde, 0xe3, 0xbc, 0xe4, 0x9e, 0xe5, 0x83, 0xe6, 0x62, 0xe7, + 0x51, 0xe8, 0x34, 0xe9, 0x1e, 0xea, 0x12, 0xeb, 0xf7, 0xeb, 0xe5, 0xec, + 0xc5, 0xed, 0xc2, 0xee, 0xb1, 0xef, 0xa6, 0xf0, 0x90, 0xf1, 0x7e, 0xf2, + 0x6f, 0xf3, 0x56, 0xf4, 0x48, 0xf5, 0x35, 0xf6, 0x29, 0xf7, 0x17, 0xf8, + 0x0a, 0xf9, 0x00, 0xfa, 0xe7, 0xfa, 0xde, 0xfb, 0xc9, 0xfc, 0xc1, 0xfd, + 0xac, 0xfe, 0xae, 0xff, 0xa2, 0x00, 0x8d, 0x01, 0x70, 0x02, 0x62, 0x03, + 0x4e, 0x04, 0x3a, 0x05, 0x26, 0x06, 0x16, 0x07, 0xff, 0x07, 0xf3, 0x08, + 0xda, 0x09, 0xbe, 0x0a, 0xb9, 0x0b, 0xa1, 0x0c, 0x9b, 0x0d, 0x7d, 0x0e, + 0x66, 0x0f, 0x54, 0x10, 0x36, 0x11, 0x20, 0x12, 0x11, 0x13, 0xf3, 0x13, + 0xea, 0x14, 0xd1, 0x15, 0xb6, 0x16, 0x9b, 0x17, 0x83, 0x18, 0x7f, 0x19, + 0x58, 0x1a, 0x53, 0x1b, 0x37, 0x1c, 0x22, 0x1d, 0x0a, 0x1e, 0xf3, 0x1e, + 0xda, 0x1f, 0xca, 0x20, 0xb1, 0x21, 0x96, 0x22, 0x70, 0x23, 0x55, 0x24, + 0x39, 0x25, 0x39, 0x26, 0x1a, 0x27, 0x07, 0x28, 0xe1, 0x28, 0xc5, 0x29, + 0xa7, 0x2a, 0x85, 0x2b, 0x70, 0x2c, 0x4e, 0x2d, 0x3e, 0x2e, 0x19, 0x2f, + 0xf3, 0x2f, 0xdf, 0x30, 0xc0, 0x31, 0xaf, 0x32, 0x93, 0x33, 0x77, 0x34, + 0x48, 0x35, 0x2a, 0x36, 0x0f, 0x37, 0xf8, 0x37, 0xd9, 0x38, 0xbe, 0x39, + 0x8b, 0x3a, 0x74, 0x3b, 0x48, 0x3c, 0x2d, 0x3d, 0xfa, 0x3d, 0xe7, 0x3e, + 0xb0, 0x3f, 0x98, 0x40, 0x67, 0x41, 0x3a, 0x42, 0x16, 0x43, 0xf4, 0x43, + 0xd8, 0x44, 0xa4, 0x45, 0x7c, 0x46, 0x4c, 0x47, 0x2a, 0x48, 0x06, 0x49, + 0xce, 0x49, 0xa5, 0x4a, 0x77, 0x4b, 0x4e, 0x4c, 0x13, 0x4d, 0xdf, 0x4d, + 0xaa, 0x4e, 0x74, 0x4f, 0x3d, 0x50, 0xfc, 0x50, 0xbd, 0x51, 0x8c, 0x52, + 0x3e, 0x53, 0xfe, 0x53, 0x99, 0x54, 0x57, 0x55, 0xfc, 0x55, 0xab, 0x56, + 0x45, 0x57, 0xd6, 0x57, 0x87, 0x58, 0x2f, 0x59, 0xbf, 0x59, 0x48, 0x5a, + 0xc7, 0x5a, 0x54, 0x5b, 0xc8, 0x5b, 0x45, 0x5c, 0xb4, 0x5c, 0x25, 0x5d, + 0x7e, 0x5d, 0xda, 0x5d, 0x36, 0x5e, 0xa5, 0x5e, 0xe9, 0x5e, 0x37, 0x5f, + 0x72, 0x5f, 0xab, 0x5f, 0xe5, 0x5f, 0x1d, 0x60, 0x4f, 0x60, 0x81, 0x60, + 0x9c, 0x60, 0xc3, 0x60, 0xdc, 0x60, 0xf7, 0x60, 0x04, 0x61, 0x16, 0x61, + 0x1b, 0x61, 0x21, 0x61, 0x20, 0x61, 0x0d, 0x61, 0x0b, 0x61, 0xf0, 0x60, + 0xe5, 0x60, 0xc7, 0x60, 0xb3, 0x60, 0x98, 0x60, 0x7c, 0x60, 0x59, 0x60, + 0x4c, 0x60, 0x24, 0x60, 0x0d, 0x60, 0xdf, 0x5f, 0xb7, 0x5f, 0x87, 0x5f, + 0x6b, 0x5f, 0x44, 0x5f, 0x28, 0x5f, 0xf5, 0x5e, 0xbd, 0x5e, 0x8f, 0x5e, + 0x5c, 0x5e, 0x2a, 0x5e, 0xfe, 0x5d, 0xcd, 0x5d, 0xa4, 0x5d, 0x75, 0x5d, + 0x4d, 0x5d, 0x11, 0x5d, 0xdf, 0x5c, 0xa9, 0x5c, 0x78, 0x5c, 0x42, 0x5c, + 0x13, 0x5c, 0xde, 0x5b, 0xaf, 0x5b, 0x75, 0x5b, 0x3e, 0x5b, 0xfd, 0x5a, + 0xbc, 0x5a, 0x90, 0x5a, 0x54, 0x5a, 0x1f, 0x5a, 0xe5, 0x59, 0xc2, 0x59, + 0x80, 0x59, 0x39, 0x59, 0x0a, 0x59, 0xd6, 0x58, 0x96, 0x58, 0x55, 0x58, + 0x1e, 0x58, 0xf1, 0x57, 0xc8, 0x57, 0x7e, 0x57, 0x44, 0x57, 0x11, 0x57, + 0xd4, 0x56, 0x93, 0x56, 0x4c, 0x56, 0x11, 0x56, 0xd7, 0x55, 0xae, 0x55, + 0x72, 0x55, 0x3c, 0x55, 0x0c, 0x55, 0xd1, 0x54, 0x98, 0x54, 0x63, 0x54, + 0x2b, 0x54, 0xf8, 0x53, 0xc6, 0x53, 0x81, 0x53, 0x4b, 0x53, 0x19, 0x53, + 0xea, 0x52, 0xb2, 0x52, 0x7e, 0x52, 0x30, 0x52, 0xc5, 0x51, 0x46, 0x51, + 0xca, 0x50, 0x55, 0x50, 0xd7, 0x4f, 0x5d, 0x4f, 0xe4, 0x4e, 0x79, 0x4e, + 0xfb, 0x4d, 0x83, 0x4d, 0x02, 0x4d, 0x8a, 0x4c, 0x1f, 0x4c, 0x98, 0x4b, + 0x20, 0x4b, 0xa7, 0x4a, 0x36, 0x4a, 0xc0, 0x49, 0x44, 0x49, 0xc3, 0x48, + 0x44, 0x48, 0xd5, 0x47, 0x59, 0x47, 0xe6, 0x46, 0x63, 0x46, 0xf8, 0x45, + 0x79, 0x45, 0xfa, 0x44, 0x80, 0x44, 0x01, 0x44, 0x7a, 0x43, 0x04, 0x43, + 0x85, 0x42, 0x07, 0x42, 0x92, 0x41, 0x17, 0x41, 0x94, 0x40, 0x16, 0x40, + 0x9f, 0x3f, 0x20, 0x3f, 0x9c, 0x3e, 0x29, 0x3e, 0x9c, 0x3d, 0x20, 0x3d, + 0x88, 0x3c, 0x0c, 0x3c, 0x87, 0x3b, 0x07, 0x3b, 0x89, 0x3a, 0xfb, 0x39, + 0x6f, 0x39, 0xe7, 0x38, 0x55, 0x38, 0xcf, 0x37, 0x43, 0x37, 0xb5, 0x36, + 0x2a, 0x36, 0x9c, 0x35, 0x0a, 0x35, 0x83, 0x34, 0xe6, 0x33, 0x53, 0x33, + 0xba, 0x32, 0x1d, 0x32, 0x78, 0x31, 0xcb, 0x30, 0x34, 0x30, 0x8e, 0x2f, + 0xf6, 0x2e, 0x56, 0x2e, 0xab, 0x2d, 0xfe, 0x2c, 0x4c, 0x2c, 0x9f, 0x2b, + 0xed, 0x2a, 0x36, 0x2a, 0x7b, 0x29, 0xb9, 0x28, 0x02, 0x28, 0x41, 0x27, + 0x81, 0x26, 0xb9, 0x25, 0xfb, 0x24, 0x2d, 0x24, 0x66, 0x23, 0x98, 0x22, + 0xc6, 0x21, 0xe9, 0x20, 0x0d, 0x20, 0x28, 0x1f, 0x4c, 0x1e, 0x64, 0x1d, + 0x66, 0x1c, 0x8c, 0x1b, 0x96, 0x1a, 0xac, 0x19, 0xb2, 0x18, 0xbb, 0x17, + 0xc2, 0x16, 0xc7, 0x15, 0xcb, 0x14, 0xcd, 0x13, 0xc4, 0x12, 0xca, 0x11, + 0xb6, 0x10, 0xb8, 0x0f, 0xa3, 0x0e, 0x9e, 0x0d, 0x88, 0x0c, 0x86, 0x0b, + 0x7b, 0x0a, 0x7c, 0x09, 0x6d, 0x08, 0x5b, 0x07, 0x4a, 0x06, 0x38, 0x05, + 0x2f, 0x04, 0x1c, 0x03, 0x10, 0x02, 0xf6, 0x00, 0xe9, 0xff, 0xe5, 0xfe, + 0xcf, 0xfd, 0xc8, 0xfc, 0xb1, 0xfb, 0xa7, 0xfa, 0x8d, 0xf9, 0x7b, 0xf8, + 0x7e, 0xf7, 0x77, 0xf6, 0x68, 0xf5, 0x62, 0xf4, 0x49, 0xf3, 0x42, 0xf2, + 0x41, 0xf1, 0x3e, 0xf0, 0x49, 0xef, 0x47, 0xee, 0x56, 0xed, 0x46, 0xec, + 0x56, 0xeb, 0x5c, 0xea, 0x6c, 0xe9, 0x7d, 0xe8, 0x9c, 0xe7, 0x99, 0xe6, + 0xbf, 0xe5, 0xc9, 0xe4, 0xe5, 0xe3, 0xfd, 0xe2, 0x17, 0xe2, 0x26, 0xe1, + 0x44, 0xe0, 0x6d, 0xdf, 0x9f, 0xde, 0xc5, 0xdd, 0xec, 0xdc, 0x26, 0xdc, + 0x58, 0xdb, 0x91, 0xda, 0xb7, 0xd9, 0xf5, 0xd8, 0x27, 0xd8, 0x63, 0xd7, + 0x96, 0xd6, 0xd5, 0xd5, 0x1a, 0xd5, 0x52, 0xd4, 0x9d, 0xd3, 0xde, 0xd2, + 0x27, 0xd2, 0x6c, 0xd1, 0xb3, 0xd0, 0xf6, 0xcf, 0x51, 0xcf, 0x98, 0xce, + 0xe9, 0xcd, 0x2f, 0xcd, 0x88, 0xcc, 0xdc, 0xcb, 0x41, 0xcb, 0x9f, 0xca, + 0x01, 0xca, 0x60, 0xc9, 0xc4, 0xc8, 0x13, 0xc8, 0x7e, 0xc7, 0xe2, 0xc6, + 0x51, 0xc6, 0xb6, 0xc5, 0x1a, 0xc5, 0x8e, 0xc4, 0xf6, 0xc3, 0x74, 0xc3, + 0xdf, 0xc2, 0x59, 0xc2, 0xd2, 0xc1, 0x47, 0xc1, 0xbe, 0xc0, 0x3b, 0xc0, + 0xbe, 0xbf, 0x3e, 0xbf, 0xc4, 0xbe, 0x39, 0xbe, 0xbf, 0xbd, 0x3e, 0xbd, + 0xd7, 0xbc, 0x5d, 0xbc, 0xec, 0xbb, 0x73, 0xbb, 0x07, 0xbb, 0x96, 0xba, + 0x24, 0xba, 0xb5, 0xb9, 0x49, 0xb9, 0xdd, 0xb8, 0x76, 0xb8, 0x02, 0xb8, + 0xa8, 0xb7, 0x3c, 0xb7, 0xee, 0xb6, 0x82, 0xb6, 0x2b, 0xb6, 0xc3, 0xb5, + 0x6e, 0xb5, 0x14, 0xb5, 0xc4, 0xb4, 0x6b, 0xb4, 0x20, 0xb4, 0xd2, 0xb3, + 0x78, 0xb3, 0x2c, 0xb3, 0xe6, 0xb2, 0x9e, 0xb2, 0x58, 0xb2, 0x1a, 0xb2, + 0xea, 0xb1, 0xa6, 0xb1, 0x63, 0xb1, 0x2b, 0xb1, 0xf3, 0xb0, 0xb8, 0xb0, + 0x7b, 0xb0, 0x4e, 0xb0, 0x20, 0xb0, 0xf9, 0xaf, 0xc6, 0xaf, 0xa2, 0xaf, + 0x84, 0xaf, 0x5e, 0xaf, 0x44, 0xaf, 0x21, 0xaf, 0x06, 0xaf, 0xe9, 0xae, + 0xe2, 0xae, 0xd0, 0xae, 0xc3, 0xae, 0xba, 0xae, 0xc1, 0xae, 0xaf, 0xae, + 0xbc, 0xae, 0xb5, 0xae, 0xc0, 0xae, 0xc3, 0xae, 0xd7, 0xae, 0xdd, 0xae, + 0xfb, 0xae, 0x0a, 0xaf, 0x16, 0xaf, 0x37, 0xaf, 0x4a, 0xaf, 0x70, 0xaf, + 0x86, 0xaf, 0xa9, 0xaf, 0xc7, 0xaf, 0xec, 0xaf, 0x12, 0xb0, 0x42, 0xb0, + 0x66, 0xb0, 0x91, 0xb0, 0xc0, 0xb0, 0xee, 0xb0, 0x1a, 0xb1, 0x4c, 0xb1, + 0x77, 0xb1, 0xb3, 0xb1, 0xdd, 0xb1, 0x10, 0xb2, 0x47, 0xb2, 0x70, 0xb2, + 0xb8, 0xb2, 0xef, 0xb2, 0x26, 0xb3, 0x64, 0xb3, 0x90, 0xb3, 0xd8, 0xb3, + 0x07, 0xb4, 0x4b, 0xb4, 0x83, 0xb4, 0xc7, 0xb4, 0xf4, 0xb4, 0x35, 0xb5, + 0x70, 0xb5, 0xbc, 0xb5, 0xf0, 0xb5, 0x39, 0xb6, 0x7d, 0xb6, 0xb7, 0xb6, + 0xfa, 0xb6, 0x2e, 0xb7, 0x7d, 0xb7, 0xbb, 0xb7, 0x01, 0xb8, 0x39, 0xb8, + 0x80, 0xb8, 0xbd, 0xb8, 0x05, 0xb9, 0x46, 0xb9, 0x94, 0xb9, 0xcd, 0xb9, + 0x17, 0xba, 0x5b, 0xba, 0x9e, 0xba, 0xdf, 0xba, 0x27, 0xbb, 0x6a, 0xbb, + 0xbc, 0xbb, 0xf6, 0xbb, 0x3a, 0xbc, 0x83, 0xbc, 0xc3, 0xbc, 0x16, 0xbd, + 0x58, 0xbd, 0xa2, 0xbd, 0xe0, 0xbd, 0x24, 0xbe, 0x70, 0xbe, 0xa1, 0xbe, + 0xfa, 0xbe, 0x37, 0xbf, 0x8d, 0xbf, 0xc9, 0xbf, 0x1d, 0xc0, 0x5d, 0xc0, + 0xa6, 0xc0, 0xe6, 0xc0, 0x2f, 0xc1, 0x7a, 0xc1, 0xcb, 0xc1, 0x2f, 0xc2, + 0x95, 0xc2, 0xfa, 0xc2, 0x55, 0xc3, 0xbb, 0xc3, 0x1e, 0xc4, 0x86, 0xc4, + 0xec, 0xc4, 0x4b, 0xc5, 0xab, 0xc5, 0x04, 0xc6, 0x72, 0xc6, 0xc6, 0xc6, + 0x3a, 0xc7, 0x8e, 0xc7, 0xfd, 0xc7, 0x5a, 0xc8, 0xc0, 0xc8, 0x17, 0xc9, + 0x79, 0xc9, 0xd5, 0xc9, 0x43, 0xca, 0x98, 0xca, 0x05, 0xcb, 0x64, 0xcb, + 0xc3, 0xcb, 0x1e, 0xcc, 0x81, 0xcc, 0xe3, 0xcc, 0x40, 0xcd, 0xa6, 0xcd, + 0x0a, 0xce, 0x6a, 0xce, 0xc0, 0xce, 0x26, 0xcf, 0x81, 0xcf, 0xf0, 0xcf, + 0x48, 0xd0, 0xad, 0xd0, 0x07, 0xd1, 0x71, 0xd1, 0xca, 0xd1, 0x2b, 0xd2, + 0x8a, 0xd2, 0xed, 0xd2, 0x50, 0xd3, 0xa1, 0xd3, 0x0f, 0xd4, 0x6f, 0xd4, + 0xd6, 0xd4, 0x30, 0xd5, 0x93, 0xd5, 0xf6, 0xd5, 0x55, 0xd6, 0xb5, 0xd6, + 0x12, 0xd7, 0x7b, 0xd7, 0xde, 0xd7, 0x34, 0xd8, 0x93, 0xd8, 0xe9, 0xd8, + 0x61, 0xd9, 0xbb, 0xd9, 0x2b, 0xda, 0x88, 0xda, 0xeb, 0xda, 0x4f, 0xdb, + 0xb9, 0xdb, 0x21, 0xdc, 0x80, 0xdc, 0xf7, 0xdc, 0x53, 0xdd, 0xbb, 0xdd, + 0x2b, 0xde, 0xa4, 0xde, 0x05, 0xdf, 0x74, 0xdf, 0xd8, 0xdf, 0x44, 0xe0, + 0xb4, 0xe0, 0x26, 0xe1, 0x91, 0xe1, 0x01, 0xe2, 0x77, 0xe2, 0xeb, 0xe2, + 0x5e, 0xe3, 0xc7, 0xe3, 0x44, 0xe4, 0xb2, 0xe4, 0x25, 0xe5, 0xa3, 0xe5, + 0x15, 0xe6, 0x97, 0xe6, 0x0b, 0xe7, 0x8b, 0xe7, 0x10, 0xe8, 0x7d, 0xe8, + 0x06, 0xe9, 0x74, 0xe9, 0xff, 0xe9, 0x82, 0xea, 0x01, 0xeb, 0x85, 0xeb, + 0xfa, 0xeb, 0x91, 0xec, 0x07, 0xed, 0x8f, 0xed, 0x15, 0xee, 0x9a, 0xee, + 0x26, 0xef, 0xa5, 0xef, 0x26, 0xf0, 0xb2, 0xf0, 0x3e, 0xf1, 0xca, 0xf1, + 0x45, 0xf2, 0xcc, 0xf2, 0x51, 0xf3, 0xdc, 0xf3, 0x5c, 0xf4, 0xe8, 0xf4, + 0x6e, 0xf5, 0xf9, 0xf5, 0x79, 0xf6, 0xf9, 0xf6, 0x7d, 0xf7, 0x08, 0xf8, + 0x91, 0xf8, 0x18, 0xf9, 0x95, 0xf9, 0x18, 0xfa, 0xa5, 0xfa, 0x21, 0xfb, + 0xa9, 0xfb, 0x2a, 0xfc, 0xa7, 0xfc, 0x23, 0xfd, 0xa3, 0xfd, 0x2b, 0xfe, + 0x9c, 0xfe, 0x2b, 0xff, 0xa0, 0xff, 0x1c, 0x00, 0x9a, 0x00, 0x11, 0x01, + 0x9a, 0x01, 0x14, 0x02, 0x8c, 0x02, 0x07, 0x03, 0x84, 0x03, 0xf7, 0x03, + 0x75, 0x04, 0xf3, 0x04, 0x65, 0x05, 0xe8, 0x05, 0x54, 0x06, 0xd3, 0x06, + 0x48, 0x07, 0xc2, 0x07, 0x38, 0x08, 0xad, 0x08, 0x28, 0x09, 0x99, 0x09, + 0x11, 0x0a, 0x79, 0x0a, 0xf5, 0x0a, 0x5c, 0x0b, 0xd1, 0x0b, 0x3f, 0x0c, + 0xb5, 0x0c, 0x2c, 0x0d, 0x9a, 0x0d, 0x0b, 0x0e, 0x74, 0x0e, 0xe6, 0x0e, + 0x45, 0x0f, 0xbd, 0x0f, 0x2f, 0x10, 0x9a, 0x10, 0x05, 0x11, 0x6c, 0x11, + 0xdb, 0x11, 0x40, 0x12, 0xaa, 0x12, 0x14, 0x13, 0x81, 0x13, 0xe9, 0x13, + 0x4d, 0x14, 0xb9, 0x14, 0x18, 0x15, 0x88, 0x15, 0xe6, 0x15, 0x58, 0x16, + 0xb9, 0x16, 0x1c, 0x17, 0x7e, 0x17, 0xe3, 0x17, 0x43, 0x18, 0xac, 0x18, + 0x08, 0x19, 0x6d, 0x19, 0xce, 0x19, 0x34, 0x1a, 0x90, 0x1a, 0xf5, 0x1a, + 0x53, 0x1b, 0xbb, 0x1b, 0x07, 0x1c, 0x6f, 0x1c, 0xc2, 0x1c, 0x28, 0x1d, + 0x84, 0x1d, 0xe8, 0x1d, 0x35, 0x1e, 0xa2, 0x1e, 0xf8, 0x1e, 0x59, 0x1f, + 0xb8, 0x1f, 0x0c, 0x20, 0x69, 0x20, 0xbe, 0x20, 0x19, 0x21, 0x66, 0x21, + 0xc6, 0x21, 0x1f, 0x22, 0x70, 0x22, 0xbe, 0x22, 0x18, 0x23, 0x72, 0x23, + 0xbf, 0x23, 0x0f, 0x24, 0x67, 0x24, 0xc0, 0x24, 0x08, 0x25, 0x51, 0x25, + 0xa6, 0x25, 0xf4, 0x25, 0x42, 0x26, 0x93, 0x26, 0xd6, 0x26, 0x25, 0x27, + 0x6c, 0x27, 0xb7, 0x27, 0x07, 0x28, 0x49, 0x28, 0x96, 0x28, 0xda, 0x28, + 0x22, 0x29, 0x66, 0x29, 0xa4, 0x29, 0xe8, 0x29, 0x20, 0x2a, 0x62, 0x2a, + 0xa9, 0x2a, 0xe5, 0x2a, 0x21, 0x2b, 0x5a, 0x2b, 0x97, 0x2b, 0xc1, 0x2b, + 0xfe, 0x2b, 0x28, 0x2c, 0x57, 0x2c, 0x88, 0x2c, 0xae, 0x2c, 0xd3, 0x2c, + 0xfa, 0x2c, 0x17, 0x2d, 0x33, 0x2d, 0x4b, 0x2d, 0x5d, 0x2d, 0x68, 0x2d, + 0x81, 0x2d, 0x92, 0x2d, 0x9e, 0x2d, 0xa9, 0x2d, 0xbb, 0x2d, 0xc3, 0x2d, + 0xcd, 0x2d, 0xd5, 0x2d, 0xcd, 0x2d, 0xdc, 0x2d, 0xe3, 0x2d, 0xe1, 0x2d, + 0xdd, 0x2d, 0xd9, 0x2d, 0xd7, 0x2d, 0xcf, 0x2d, 0xe0, 0x2d, 0xd2, 0x2d, + 0xd2, 0x2d, 0xcb, 0x2d, 0xb7, 0x2d, 0xb6, 0x2d, 0xa1, 0x2d, 0x9e, 0x2d, + 0x8b, 0x2d, 0x84, 0x2d, 0x68, 0x2d, 0x6a, 0x2d, 0x4e, 0x2d, 0x45, 0x2d, + 0x2f, 0x2d, 0x18, 0x2d, 0x15, 0x2d, 0xef, 0x2c, 0xe8, 0x2c, 0xc9, 0x2c, + 0xc7, 0x2c, 0xaa, 0x2c, 0x9b, 0x2c, 0x7c, 0x2c, 0x64, 0x2c, 0x3c, 0x2c, + 0x2e, 0x2c, 0x16, 0x2c, 0x05, 0x2c, 0xe1, 0x2b, 0xc8, 0x2b, 0xb5, 0x2b, + 0x9a, 0x2b, 0x7c, 0x2b, 0x61, 0x2b, 0x3f, 0x2b, 0x21, 0x2b, 0x01, 0x2b, + 0xee, 0x2a, 0xd0, 0x2a, 0xb3, 0x2a, 0x95, 0x2a, 0x6d, 0x2a, 0x50, 0x2a, + 0x2b, 0x2a, 0x0b, 0x2a, 0xe9, 0x29, 0xd1, 0x29, 0xa8, 0x29, 0x97, 0x29, + 0x6c, 0x29, 0x51, 0x29, 0x24, 0x29, 0x03, 0x29, 0xe6, 0x28, 0xbe, 0x28, + 0xa1, 0x28, 0x80, 0x28, 0x64, 0x28, 0x38, 0x28, 0x12, 0x28, 0xf0, 0x27, + 0xd3, 0x27, 0xac, 0x27, 0x94, 0x27, 0x67, 0x27, 0x4a, 0x27, 0x1c, 0x27, + 0xf7, 0x26, 0xd1, 0x26, 0xb6, 0x26, 0x8d, 0x26, 0x6e, 0x26, 0x4b, 0x26, + 0x25, 0x26, 0x02, 0x26, 0xd8, 0x25, 0xbe, 0x25, 0x93, 0x25, 0x7c, 0x25, + 0x4a, 0x25, 0x27, 0x25, 0x07, 0x25, 0xdc, 0x24, 0xbb, 0x24, 0x9a, 0x24, + 0x78, 0x24, 0x4c, 0x24, 0x26, 0x24, 0x00, 0x24, 0xd7, 0x23, 0xc0, 0x23, + 0x94, 0x23, 0x71, 0x23, 0x45, 0x23, 0x1c, 0x23, 0x00, 0x23, 0xd4, 0x22, + 0xb5, 0x22, 0x8e, 0x22, 0x67, 0x22, 0x39, 0x22, 0x00, 0x22, 0xbd, 0x21, + 0x87, 0x21, 0x46, 0x21, 0x01, 0x21, 0xca, 0x20, 0x89, 0x20, 0x4a, 0x20, + 0x17, 0x20, 0xd6, 0x1f, 0x9a, 0x1f, 0x5e, 0x1f, 0x20, 0x1f, 0xe0, 0x1e, + 0xa3, 0x1e, 0x5f, 0x1e, 0x29, 0x1e, 0xf0, 0x1d, 0xb8, 0x1d, 0x78, 0x1d, + 0x36, 0x1d, 0x04, 0x1d, 0xc6, 0x1c, 0x8b, 0x1c, 0x4d, 0x1c, 0x18, 0x1c, + 0xd9, 0x1b, 0x97, 0x1b, 0x5c, 0x1b, 0x2b, 0x1b, 0xf4, 0x1a, 0xb1, 0x1a, + 0x7c, 0x1a, 0x32, 0x1a, 0x02, 0x1a, 0xc6, 0x19, 0x8b, 0x19, 0x59, 0x19, + 0x10, 0x19, 0xd7, 0x18, 0x9c, 0x18, 0x62, 0x18, 0x22, 0x18, 0xe8, 0x17, + 0xb1, 0x17, 0x7c, 0x17, 0x34, 0x17, 0xf9, 0x16, 0xc0, 0x16, 0x8b, 0x16, + 0x55, 0x16, 0x14, 0x16, 0xdd, 0x15, 0x9f, 0x15, 0x65, 0x15, 0x2b, 0x15, + 0xea, 0x14, 0xb9, 0x14, 0x70, 0x14, 0x3d, 0x14, 0x05, 0x14, 0xc1, 0x13, + 0x86, 0x13, 0x45, 0x13, 0x09, 0x13, 0xca, 0x12, 0x90, 0x12, 0x57, 0x12, + 0x1a, 0x12, 0xe1, 0x11, 0x9b, 0x11, 0x61, 0x11, 0x1d, 0x11, 0xe1, 0x10, + 0x9d, 0x10, 0x64, 0x10, 0x17, 0x10, 0xde, 0x0f, 0xa1, 0x0f, 0x60, 0x0f, + 0x1b, 0x0f, 0xd8, 0x0e, 0x90, 0x0e, 0x5b, 0x0e, 0x0e, 0x0e, 0xd3, 0x0d, + 0x86, 0x0d, 0x4d, 0x0d, 0xf5, 0x0c, 0xba, 0x0c, 0x68, 0x0c, 0x2a, 0x0c, + 0xde, 0x0b, 0x94, 0x0b, 0x4e, 0x0b, 0x07, 0x0b, 0xbb, 0x0a, 0x6c, 0x0a, + 0x25, 0x0a, 0xd4, 0x09, 0x89, 0x09, 0x39, 0x09, 0xe6, 0x08, 0xa3, 0x08, + 0x4f, 0x08, 0x02, 0x08, 0xa7, 0x07, 0x5f, 0x07, 0x08, 0x07, 0xba, 0x06, + 0x68, 0x06, 0x1f, 0x06, 0xc5, 0x05, 0x7a, 0x05, 0x1f, 0x05, 0xd7, 0x04, + 0x85, 0x04, 0x31, 0x04, 0xde, 0x03, 0x89, 0x03, 0x3a, 0x03, 0xe9, 0x02, + 0x96, 0x02, 0x47, 0x02, 0xf7, 0x01, 0xa4, 0x01, 0x5d, 0x01, 0x06, 0x01, + 0xb9, 0x00, 0x00, 0x00 +}; +unsigned int kick_raw_len = 6352; diff --git a/third-party/TeensyVariablePlayback/keywords.txt b/third-party/TeensyVariablePlayback/keywords.txt new file mode 100644 index 0000000..6f5a33f --- /dev/null +++ b/third-party/TeensyVariablePlayback/keywords.txt @@ -0,0 +1,12 @@ +AudioPlayArrayResmp KEYWORD2 +AudioPlaySdResmp KEYWORD2 +playRaw KEYWORD2 +playWav KEYWORD2 +isPlaying KEYWORD2 +setPlaybackRate KEYWORD2 +setLoopType KEYWORD2 +startLoop KEYWORD2 +enableInterpolation KEYWORD2 +looptype_none LITERAL1 +looptype_repeat LITERAL1 +looptype_pingpong LITERAL1 \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/library.json b/third-party/TeensyVariablePlayback/library.json new file mode 100644 index 0000000..c003a58 --- /dev/null +++ b/third-party/TeensyVariablePlayback/library.json @@ -0,0 +1,37 @@ +{ + "name": "TeensyVariablePlayback", + "frameworks": "Arduino", + "platforms": "Teensy", + "keywords": "sound, audio, sample, resample, pitch, interpolation, legrange, sampler, playback, speed", + "description": "Teensy Variable Playback", + "url": "https://github.com/newdigate/teensy-variable-playback", + "version": "1.0.12", + "export": { + "exclude": [ + ".vscode", + ".github", + "extras", + "test", + "cmake", + "docs" + ] + }, + "authors": + { + "name": "Nic Newdigate", + "maintainer": true + }, + "repository": + { + "type": "git", + "url": "https://github.com/newdigate/teensy-variable-playback" + }, + "dependencies":[{ + "name": "Audio", + "frameworks": "arduino" + }], + "examples": [ + "examples/*/*.ino", + "examples/*/*/*.ino" + ] + } \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/library.properties b/third-party/TeensyVariablePlayback/library.properties new file mode 100644 index 0000000..5a8eea4 --- /dev/null +++ b/third-party/TeensyVariablePlayback/library.properties @@ -0,0 +1,9 @@ +name=TeensyVariablePlayback +version=1.0.12 +author=Nic Newdigate +maintainer=Nic Newdigate +sentence=Play samples at variable pitch using Teensy Audio Library +paragraph=Adds AudioPlaySdRawResmp, AudioPlaySdWavResmp, AudioPlayArrayResmp objects to with pitch and loop controls +category=Signal Input/Output +url=https://github.com/newdigate/teensy-variable-playback +architectures=* diff --git a/third-party/TeensyVariablePlayback/src/CMakeLists.linux.cmake.in b/third-party/TeensyVariablePlayback/src/CMakeLists.linux.cmake.in new file mode 100644 index 0000000..d551486 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/CMakeLists.linux.cmake.in @@ -0,0 +1,52 @@ +message("building for linux...") +add_definitions(-DBUILD_FOR_LINUX) + +set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/teensy_variable_playback/) +set(LIB_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib/teensy_variable_playback ) + +find_package(teensy_x86_stubs) +include_directories(${teensy_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_audio_x86_stubs) +include_directories(${teensy_audio_x86_stubs_INCLUDE_DIR}) + +find_package(teensy_x86_sd_stubs) +include_directories(${teensy_x86_sd_stubs_INCLUDE_DIR}) + +add_library(teensy_variable_playback STATIC + ${HEADER_FILES} + ${SOURCE_FILES} + ) + +set_target_properties(teensy_variable_playback PROPERTIES PUBLIC_HEADER "${HEADER_FILES}") +set_target_properties(teensy_variable_playback PROPERTIES LINKER_LANGUAGE C) + +include(CMakePackageConfigHelpers) +configure_package_config_file(../cmake/teensy_variable_playback.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/teensy_variable_playbackConfig.cmake + INSTALL_DESTINATION ${LIB_INSTALL_DIR}/teensy_variable_playback/cmake + PATH_VARS) + +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/teensy_variable_playbackConfigVersion.cmake + VERSION ${teensy_variable_playback_VERSION} + COMPATIBILITY SameMajorVersion ) + +install(TARGETS teensy_variable_playback DESTINATION + LIBRARY DESTINATION ${LIB_INSTALL_DIR} + ARCHIVE DESTINATION ${LIB_INSTALL_DIR} + PUBLIC_HEADER DESTINATION "include/teensy_variable_playback" + ) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/teensy_variable_playbackConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/teensy_variable_playbackConfigVersion.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/uninstall.cmake + DESTINATION "lib/cmake/teensy_variable_playback" ) + +## +# copied from: https://gist.github.com/royvandam/3033428 +# Add uninstall target +# Requirements: Copy the uninstall.cmake file to the appropriate CMAKE_MODULE_PATH. +add_custom_target(uninstall + "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall.cmake") \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/src/CMakeLists.txt b/third-party/TeensyVariablePlayback/src/CMakeLists.txt new file mode 100644 index 0000000..365b7a3 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.5) +project(teensy_variable_playback C CXX) +set(teensy_variable_playback_VERSION 1.0.0) +set(CMAKE_CXX_STANDARD 11) +set(SOURCE_FILES + playsdresmp.cpp + ResamplingSdReader.cpp + ResamplingArrayReader.cpp + playarrayresmp.cpp + interpolation.cpp + IndexableFile.cpp) + +set(HEADER_FILES + loop_type.h + playresmp.h + playsdresmp.h + ResamplingSdReader.h + waveheaderparser.h + ResamplingArrayReader.h + playarrayresmp.h + interpolation.h + TeensyVariablePlayback.h + IndexableFile.h) + +#set(CMAKE_VERBOSE_MAKEFILE 1) +if (NOT DEFINED TEENSY_VERSION) + include(CMakeLists.linux.cmake.in) +else() + teensy_add_library( + teensy_variable_playback + ${SOURCE_FILES} + ) + + add_custom_target(installarduino + "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/install_arduino_library.cmake") +endif() \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/src/IndexableFile.cpp b/third-party/TeensyVariablePlayback/src/IndexableFile.cpp new file mode 100644 index 0000000..541c7af --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/IndexableFile.cpp @@ -0,0 +1 @@ +#include "IndexableFile.h" diff --git a/third-party/TeensyVariablePlayback/src/IndexableFile.h b/third-party/TeensyVariablePlayback/src/IndexableFile.h new file mode 100644 index 0000000..30f423e --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/IndexableFile.h @@ -0,0 +1,93 @@ +#ifndef TEENSY_RESAMPLING_INDEXABLE_FILE_H +#define TEENSY_RESAMPLING_INDEXABLE_FILE_H + +#include +#include +#include + +namespace newdigate { + + +struct indexedbuffer { + uint32_t index; + int16_t buffer_size; + int16_t *buffer; +}; + +constexpr bool isPowerOf2(size_t value){ + return !(value == 0) && !(value & (value - 1)); +} + +template // BUFFER_SIZE needs to be a power of two +class IndexableFile { +public: + static_assert(isPowerOf2(BUFFER_SIZE), "BUFFER_SIZE must be a power of 2"); + + static constexpr size_t element_size = sizeof(int16_t); + size_t buffer_to_index_shift; + IndexableFile(const char *filename) : + _buffers(), + buffer_to_index_shift(log2(BUFFER_SIZE)) { + _filename = new char[strlen(filename)+1] {0}; + memcpy(_filename, filename, strlen(filename)); + _file = SD.open(_filename); + } + + int16_t &operator[](int i) { + int32_t indexFor_i = i >> buffer_to_index_shift; + indexedbuffer *match = find_with_index(indexFor_i); + if (match == nullptr) { + if (_buffers.size() > MAX_NUM_BUFFERS - 1) { + indexedbuffer *first = _buffers[0]; + _buffers.erase(_buffers.begin()); + delete [] first->buffer; + delete first; + } + indexedbuffer *next = new indexedbuffer(); + next->index = indexFor_i; + next->buffer = new int16_t[BUFFER_SIZE]; + size_t basePos = indexFor_i << buffer_to_index_shift; + size_t seekPos = basePos * element_size; + _file.seek(seekPos); + int16_t bytesRead = _file.read(next->buffer, BUFFER_SIZE * element_size); + #ifndef TEENSYDUINO + if (!_file.available()){ + _file.close(); + __disable_irq(); + _file = SD.open(_filename); + __enable_irq(); + } + #endif + next->buffer_size = bytesRead; + _buffers.push_back(next); + match = next; + } + return match->buffer[i % BUFFER_SIZE]; + } + + void close() { + if (_file) + _file.close(); + + if (_filename) + delete [] _filename; + _filename = nullptr; + } +private: + File _file; + char *_filename; + std::vector _buffers; + + indexedbuffer* find_with_index(uint32_t i) { + for (auto && x : _buffers){ + if (x->index == i) { + return x; + } + } + return nullptr; + } +}; + +} + +#endif diff --git a/third-party/TeensyVariablePlayback/src/ResamplingArrayReader.cpp b/third-party/TeensyVariablePlayback/src/ResamplingArrayReader.cpp new file mode 100644 index 0000000..c3386d3 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/ResamplingArrayReader.cpp @@ -0,0 +1,340 @@ +#include "ResamplingArrayReader.h" +#include "interpolation.h" +#include "waveheaderparser.h" + +// read n samples into each buffer (1 buffer per channel) +unsigned int ResamplingArrayReader::read(void **buf, uint16_t nsamples) { + if (!_playing) return 0; + + int16_t *index[_numChannels]; + unsigned int count = 0; + for (int channel=0; channel < _numChannels; channel++) { + index[channel] = (int16_t*)buf[channel]; + } + + while (count < nsamples) { + + for (int channel=0; channel < _numChannels; channel++) { + if (readNextValue(index[channel], channel)) { + if (channel == _numChannels - 1) + count++; + index[channel]++; + } + else { + // we have reached the end of the file + + switch (_loopType) { + case looptype_repeat: + { + if (_playbackRate >= 0.0) + _bufferPosition = _loop_start; + else + _bufferPosition = _loop_finish - _numChannels; + + break; + } + + case looptype_pingpong: + { + if (_playbackRate >= 0.0) { + _bufferPosition = _loop_finish - _numChannels; + //printf("switching to reverse playback...\n"); + } + else { + _bufferPosition = _header_offset; + //printf("switching to forward playback...\n"); + } + _playbackRate = -_playbackRate; + break; + } + + case looptype_none: + default: + { + //Serial.printf("end of loop...\n"); + /* no looping - return the number of (resampled) bytes returned... */ + _playing = false; + return count; + } + } + } + } + } + return count; +} + +// read the sample value for given channel and store it at the location pointed to by the pointer 'value' +bool ResamplingArrayReader::readNextValue(int16_t *value, uint16_t channel) { + + if (_playbackRate >= 0 ) { + //forward playback + if (_bufferPosition >= _loop_finish ) + return false; + + } else if (_playbackRate < 0) { + // reverse playback + if (_bufferPosition < _header_offset) + return false; + } + + int16_t result = _sourceBuffer[_bufferPosition + channel]; + if (_interpolationType == ResampleInterpolationType::resampleinterpolation_linear) { + + double abs_remainder = abs(_remainder); + if (abs_remainder > 0.0) { + + if (_playbackRate > 0) { + if (_remainder - _playbackRate < 0.0){ + // we crossed over a whole number, make sure we update the samples for interpolation + + if (_playbackRate > 1.0) { + // need to update last sample + _interpolationPoints[channel][1].y = _sourceBuffer[_bufferPosition-_numChannels]; + } + + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = result; + if (_numInterpolationPoints < 2) + _numInterpolationPoints++; + } + } + else if (_playbackRate < 0) { + if (_remainder - _playbackRate > 0.0){ + // we crossed over a whole number, make sure we update the samples for interpolation + + if (_playbackRate < -1.0) { + // need to update last sample + _interpolationPoints[channel][1].y = _sourceBuffer[_bufferPosition+_numChannels]; + } + + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = result; + if (_numInterpolationPoints < 2) + _numInterpolationPoints++; + } + } + + if (_numInterpolationPoints > 1) { + result = abs_remainder * _interpolationPoints[channel][1].y + (1.0 - abs_remainder) * _interpolationPoints[channel][0].y; + //Serial.printf("[%f]\n", interpolation); + } + } else { + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = result; + if (_numInterpolationPoints < 2) + _numInterpolationPoints++; + + result =_interpolationPoints[channel][0].y; + //Serial.printf("%f\n", result); + } + } + else if (_interpolationType == ResampleInterpolationType::resampleinterpolation_quadratic) { + double abs_remainder = abs(_remainder); + if (abs_remainder > 0.0) { + if (_playbackRate > 0) { + if (_remainder - _playbackRate < 0.0){ + // we crossed over a whole number, make sure we update the samples for interpolation + int numberOfSamplesToUpdate = - floor(_remainder - _playbackRate); + if (numberOfSamplesToUpdate > 4) + numberOfSamplesToUpdate = 4; // if playbackrate > 4, only need to pop last 4 samples + for (int i=numberOfSamplesToUpdate; i > 0; i--) { + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = _interpolationPoints[channel][2].y; + _interpolationPoints[channel][2].y = _interpolationPoints[channel][3].y; + _interpolationPoints[channel][3].y = _sourceBuffer[_bufferPosition-(i*_numChannels)+1+channel]; + if (_numInterpolationPoints < 4) _numInterpolationPoints++; + } + } + } + else if (_playbackRate < 0) { + if (_remainder - _playbackRate > 0.0){ + // we crossed over a whole number, make sure we update the samples for interpolation + int numberOfSamplesToUpdate = ceil(_remainder - _playbackRate); + if (numberOfSamplesToUpdate > 4) + numberOfSamplesToUpdate = 4; // if playbackrate > 4, only need to pop last 4 samples + for (int i=numberOfSamplesToUpdate; i > 0; i--) { + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = _interpolationPoints[channel][2].y; + _interpolationPoints[channel][2].y = _interpolationPoints[channel][3].y; + _interpolationPoints[channel][3].y = _sourceBuffer[_bufferPosition+(i*_numChannels)-1+channel]; + if (_numInterpolationPoints < 4) _numInterpolationPoints++; + } + } + } + + if (_numInterpolationPoints >= 4) { + //int16_t interpolation = interpolate(_interpolationPoints, 1.0 + abs_remainder, 4); + int16_t interpolation + = fastinterpolate( + _interpolationPoints[channel][0].y, + _interpolationPoints[channel][1].y, + _interpolationPoints[channel][2].y, + _interpolationPoints[channel][3].y, + 1.0 + abs_remainder); + result = interpolation; + //Serial.printf("[%f]\n", interpolation); + } else + result = 0; + } else { + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = _interpolationPoints[channel][2].y; + _interpolationPoints[channel][2].y = _interpolationPoints[channel][3].y; + _interpolationPoints[channel][3].y = result; + if (_numInterpolationPoints < 4) { + _numInterpolationPoints++; + result = 0; + } else + result = _interpolationPoints[channel][1].y; + //Serial.printf("%f\n", result); + } + } + + if (channel == _numChannels - 1) { + _remainder += _playbackRate; + + auto delta = static_cast(_remainder); + _remainder -= static_cast(delta); + _bufferPosition += (delta * _numChannels); + } + + *value = result; + return true; +} + +void ResamplingArrayReader::initializeInterpolationPoints(void) { + if (_numChannels < 0) + return; + + deleteInterpolationPoints(); + _interpolationPoints = new InterpolationData*[_numChannels]; + for (int channel=0; channel < _numChannels; channel++) { + InterpolationData *interpolation = new InterpolationData[4]; + interpolation[0].y = 0.0; + interpolation[1].y = 0.0; + interpolation[2].y = 0.0; + interpolation[3].y = 0.0; + _interpolationPoints[channel] = interpolation ; + } + _numInterpolationPointsChannels = _numChannels; +} + +void ResamplingArrayReader::deleteInterpolationPoints(void) { + if (!_interpolationPoints) return; + for (int i=0; i<_numInterpolationPointsChannels; i++) { + delete [] _interpolationPoints[i]; + } + delete [] _interpolationPoints; + _interpolationPoints = nullptr; + _numInterpolationPointsChannels = 0; +} + +void ResamplingArrayReader::begin(void) +{ + if (_interpolationType != ResampleInterpolationType::resampleinterpolation_none) { + initializeInterpolationPoints(); + } + _playing = false; + _bufferPosition = _header_offset; + _file_size = 0; +} + +bool ResamplingArrayReader::playRaw(int16_t *array, uint32_t length, uint16_t numChannels) +{ + _sourceBuffer = array; + stop(); + + _header_offset = 0; + _file_size = length * 2; + _loop_start = 0; + _loop_finish = length; + setNumChannels(numChannels); + + reset(); + //updateBuffers(); + _playing = true; + return true; +} + +bool ResamplingArrayReader::playWav(int16_t *array, uint32_t length) // length == total number of 16-bit samples for all channels, including header +{ + _sourceBuffer = array; + stop(); + + wav_header wav_header; + wav_data_header data_header; + + WaveHeaderParser wavHeaderParser; + if (!wavHeaderParser.readWaveHeaderFromBuffer((const char *) array, wav_header)) { + Serial.println("Not able to read header! Aborting.... "); + return false; + } + + if (wav_header.bit_depth != 16) { + Serial.printf("Needs 16 bit audio! Aborting.... (got %d)\n", wav_header.bit_depth); + return false; + } + setNumChannels(wav_header.num_channels); + unsigned infoTagsSize; + if (!wavHeaderParser.readInfoTags((unsigned char *)array, 36, infoTagsSize)) + { + Serial.println("Not able to read header! Aborting..."); + return false; + } + + if (!wavHeaderParser.readDataHeader((unsigned char *)array, 36 + infoTagsSize, data_header)) { + Serial.println("Not able to read header! Aborting..."); + return false; + } + + + _header_offset = (44 + infoTagsSize) / 2; + _file_size = data_header.data_bytes + 44 + infoTagsSize; //2 bytes per sample + if (_file_size > length * 2){ + Serial.printf("TeensyVariablePlayback: warning: length of array in bytes (%d) is smaller than the file data size in bytes (%d) according to the header - defaulting length to filesize...", length * 2, _file_size); + _loop_finish = length; + } else + _loop_finish = _file_size / 2; + _loop_start = _header_offset; + + reset(); + _playing = true; + return true; +} + +bool ResamplingArrayReader::play() +{ + stop(); + reset(); + _playing = true; + return true; +} + +void ResamplingArrayReader::reset(){ + _numInterpolationPoints = 0; + if (_playbackRate > 0.0) { + // forward playabck - set _file_offset to first audio block in file + _bufferPosition = _header_offset; + } else { + // reverse playback - forward _file_offset to last audio block in file + _bufferPosition = _loop_finish - _numChannels; + } +} + +void ResamplingArrayReader::stop() +{ + if (_playing) { + _playing = false; + } +} + +int ResamplingArrayReader::available(void) { + return _playing; +} + +void ResamplingArrayReader::close(void) { + if (_playing) { + stop(); + deleteInterpolationPoints(); + } +} + diff --git a/third-party/TeensyVariablePlayback/src/ResamplingArrayReader.h b/third-party/TeensyVariablePlayback/src/ResamplingArrayReader.h new file mode 100644 index 0000000..bc2b5f5 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/ResamplingArrayReader.h @@ -0,0 +1,120 @@ +#ifndef TEENSYAUDIOLIBRARY_RESAMPLINGARRAYREADER_H +#define TEENSYAUDIOLIBRARY_RESAMPLINGARRAYREADER_H + +#include +#include "SD.h" +#include +#include "loop_type.h" +#include "interpolation.h" + +class ResamplingArrayReader { +public: + ResamplingArrayReader() { + + } + + void begin(void); + bool playRaw(int16_t *array, uint32_t length, uint16_t numChannels); + bool playWav(int16_t *array, uint32_t length); + bool play(); + void stop(void); + bool isPlaying(void) { return _playing; } + + unsigned int read(void **buf, uint16_t nbyte); + bool readNextValue(int16_t *value, uint16_t channelNumber); + + void setPlaybackRate(double f) { + _playbackRate = f; + if (f < 0.0 && _bufferPosition == 0) { + //_file.seek(_file_size); + _bufferPosition = _file_size/2 - _numChannels; + } + } + + float playbackRate() { + return _playbackRate; + } + + void loop(uint32_t numSamples) { + __disable_irq(); + _loop_start = _bufferPosition; + _loop_finish = _bufferPosition + numSamples * _numChannels; + _loopType = loop_type::looptype_repeat; + __enable_irq(); + } + + void setLoopType(loop_type loopType) + { + _loopType = loopType; + } + + loop_type getLoopType(){ + return _loopType; + } + + int available(void); + void reset(void); + void close(void); + + void setLoopStart(uint32_t loop_start) { + _loop_start = _header_offset + (loop_start * _numChannels); + } + + void setLoopFinish(uint32_t loop_finish) { + // sample number, (NOT byte number) + _loop_finish = _header_offset + (loop_finish * _numChannels); + } + + void setInterpolationType(ResampleInterpolationType interpolationType) { + if (interpolationType != _interpolationType) { + _interpolationType = interpolationType; + initializeInterpolationPoints(); + } + } + + int16_t getNumChannels() { + return _numChannels; + } + + void setNumChannels(uint16_t numChannels) { + if (numChannels != _numChannels) { + _numChannels = numChannels; + initializeInterpolationPoints(); + } + } + + void setHeaderSizeInBytes(uint32_t headerSizeInBytes) { + _header_offset = headerSizeInBytes / 2; + if (_bufferPosition < _header_offset) { + if (_playbackRate >= 0) { + _bufferPosition = _header_offset; + } else + _bufferPosition = _loop_finish - _numChannels; + } + } + +private: + volatile bool _playing = false; + + int32_t _file_size; + int32_t _header_offset = 0; // == (header size in bytes ) / 2 + + double _playbackRate = 1.0; + double _remainder = 0.0; + loop_type _loopType = looptype_none; + int _bufferPosition = 0; + int32_t _loop_start = 0; + int32_t _loop_finish = 0; + int16_t _numChannels = -1; + uint16_t _numInterpolationPointsChannels = 0; + int16_t *_sourceBuffer = nullptr; + + ResampleInterpolationType _interpolationType = ResampleInterpolationType::resampleinterpolation_none; + unsigned int _numInterpolationPoints = 0; + InterpolationData **_interpolationPoints = nullptr; + void initializeInterpolationPoints(void); + void deleteInterpolationPoints(void); +}; + + +#endif //TEENSYAUDIOLIBRARY_RESAMPLINGARRAYREADER_H diff --git a/third-party/TeensyVariablePlayback/src/ResamplingSdReader.cpp b/third-party/TeensyVariablePlayback/src/ResamplingSdReader.cpp new file mode 100644 index 0000000..5697c46 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/ResamplingSdReader.cpp @@ -0,0 +1,392 @@ +#include "ResamplingSdReader.h" +#include "interpolation.h" +#include "waveheaderparser.h" +bool ResamplingSdReader::isUsingSPI = false; + +// read n samples into each buffer (1 buffer per channel) +unsigned int ResamplingSdReader::read(void **buf, uint16_t nsamples) { + if (!_playing) return 0; + + int16_t *index[_numChannels]; + unsigned int count = 0; + for (int channel=0; channel < _numChannels; channel++) { + index[channel] = (int16_t*)buf[channel]; + } + + while (count < nsamples) { + + for (int channel=0; channel < _numChannels; channel++) { + if (readNextValue(index[channel], channel)) { + if (channel == _numChannels - 1) + count++; + index[channel]++; + } + else { + // we have reached the end of the file + + switch (_loopType) { + case looptype_repeat: + { + if (_playbackRate >= 0.0) + _bufferPosition = _loop_start; + else + _bufferPosition = _loop_finish / _numChannels - _numChannels; + + break; + } + + case looptype_pingpong: + { + if (_playbackRate >= 0.0) { + _bufferPosition = _loop_finish / _numChannels - _numChannels; + //printf("switching to reverse playback...\n"); + } + else { + _bufferPosition = _header_offset; + //printf("switching to forward playback...\n"); + } + _playbackRate = -_playbackRate; + break; + } + + case looptype_none: + default: + { + //Serial.printf("end of loop...\n"); + /* no looping - return the number of (resampled) bytes returned... */ + _playing = false; + if (_sourceBuffer) _sourceBuffer->close(); + _sourceBuffer = nullptr; + StopUsingSPI(); + return count; + } + } + } + } + } + return count; +} + +// read the sample value for given channel and store it at the location pointed to by the pointer 'value' +bool ResamplingSdReader::readNextValue(int16_t *value, uint16_t channel) { + + if (_playbackRate >= 0 ) { + //forward playback + if (_bufferPosition >= _loop_finish ) + return false; + + } else if (_playbackRate < 0) { + // reverse playback + if (_bufferPosition < _header_offset) + return false; + } + + newdigate::IndexableFile<128, 2> &sourceBuffer = (*_sourceBuffer); + + int16_t result = sourceBuffer[_bufferPosition + channel]; + if (_interpolationType == ResampleInterpolationType::resampleinterpolation_linear) { + + double abs_remainder = abs(_remainder); + if (abs_remainder > 0.0) { + + if (_playbackRate > 0) { + if (_remainder - _playbackRate < 0.0){ + // we crossed over a whole number, make sure we update the samples for interpolation + + if (_playbackRate > 1.0) { + // need to update last sample + _interpolationPoints[channel][1].y = sourceBuffer[_bufferPosition-_numChannels]; + } + + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = result; + if (_numInterpolationPoints < 2) + _numInterpolationPoints++; + } + } + else if (_playbackRate < 0) { + if (_remainder - _playbackRate > 0.0){ + // we crossed over a whole number, make sure we update the samples for interpolation + + if (_playbackRate < -1.0) { + // need to update last sample + _interpolationPoints[channel][1].y = sourceBuffer[_bufferPosition+_numChannels]; + } + + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = result; + if (_numInterpolationPoints < 2) + _numInterpolationPoints++; + } + } + + if (_numInterpolationPoints > 1) { + result = abs_remainder * _interpolationPoints[channel][1].y + (1.0 - abs_remainder) * _interpolationPoints[channel][0].y; + //Serial.printf("[%f]\n", interpolation); + } + } else { + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = result; + if (_numInterpolationPoints < 2) + _numInterpolationPoints++; + + result =_interpolationPoints[channel][0].y; + //Serial.printf("%f\n", result); + } + } + else if (_interpolationType == ResampleInterpolationType::resampleinterpolation_quadratic) { + double abs_remainder = abs(_remainder); + if (abs_remainder > 0.0) { + if (_playbackRate > 0) { + if (_remainder - _playbackRate < 0.0){ + // we crossed over a whole number, make sure we update the samples for interpolation + int numberOfSamplesToUpdate = - floor(_remainder - _playbackRate); + if (numberOfSamplesToUpdate > 4) + numberOfSamplesToUpdate = 4; // if playbackrate > 4, only need to pop last 4 samples + for (int i=numberOfSamplesToUpdate; i > 0; i--) { + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = _interpolationPoints[channel][2].y; + _interpolationPoints[channel][2].y = _interpolationPoints[channel][3].y; + _interpolationPoints[channel][3].y = sourceBuffer[_bufferPosition-(i*_numChannels)+1+channel]; + if (_numInterpolationPoints < 4) _numInterpolationPoints++; + } + } + } + else if (_playbackRate < 0) { + if (_remainder - _playbackRate > 0.0){ + // we crossed over a whole number, make sure we update the samples for interpolation + int numberOfSamplesToUpdate = ceil(_remainder - _playbackRate); + if (numberOfSamplesToUpdate > 4) + numberOfSamplesToUpdate = 4; // if playbackrate > 4, only need to pop last 4 samples + for (int i=numberOfSamplesToUpdate; i > 0; i--) { + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = _interpolationPoints[channel][2].y; + _interpolationPoints[channel][2].y = _interpolationPoints[channel][3].y; + _interpolationPoints[channel][3].y = sourceBuffer[_bufferPosition+(i*_numChannels)-1+channel]; + if (_numInterpolationPoints < 4) _numInterpolationPoints++; + } + } + } + + if (_numInterpolationPoints >= 4) { + //int16_t interpolation = interpolate(_interpolationPoints, 1.0 + abs_remainder, 4); + int16_t interpolation + = fastinterpolate( + _interpolationPoints[channel][0].y, + _interpolationPoints[channel][1].y, + _interpolationPoints[channel][2].y, + _interpolationPoints[channel][3].y, + 1.0 + abs_remainder); + result = interpolation; + //Serial.printf("[%f]\n", interpolation); + } else + result = 0; + } else { + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = _interpolationPoints[channel][2].y; + _interpolationPoints[channel][2].y = _interpolationPoints[channel][3].y; + _interpolationPoints[channel][3].y = result; + if (_numInterpolationPoints < 4) { + _numInterpolationPoints++; + result = 0; + } else + result = _interpolationPoints[channel][1].y; + //Serial.printf("%f\n", result); + } + } + + if (channel == _numChannels - 1) { + _remainder += _playbackRate; + + auto delta = static_cast(_remainder); + _remainder -= static_cast(delta); + _bufferPosition += (delta * _numChannels); + } + + *value = result; + return true; +} + +void ResamplingSdReader::initializeInterpolationPoints(void) { + if (_numChannels < 0) + return; + + deleteInterpolationPoints(); + _interpolationPoints = new InterpolationData*[_numChannels]; + for (int channel=0; channel < _numChannels; channel++) { + InterpolationData *interpolation = new InterpolationData[4]; + interpolation[0].y = 0.0; + interpolation[1].y = 0.0; + interpolation[2].y = 0.0; + interpolation[3].y = 0.0; + _interpolationPoints[channel] = interpolation ; + } + _numInterpolationPointsChannels = _numChannels; +} + +void ResamplingSdReader::deleteInterpolationPoints(void) { + if (!_interpolationPoints) return; + for (int i=0; i<_numInterpolationPointsChannels; i++) { + delete [] _interpolationPoints[i]; + } + delete [] _interpolationPoints; + _interpolationPoints = nullptr; + _numInterpolationPointsChannels = 0; +} + +void ResamplingSdReader::begin(void) +{ + if (_interpolationType != ResampleInterpolationType::resampleinterpolation_none) { + initializeInterpolationPoints(); + } + _playing = false; + _bufferPosition = _header_offset; + _file_size = 0; +} + +bool ResamplingSdReader::playRaw(const char *filename, uint16_t numChannels) { + return play(filename, false, numChannels); +} + +bool ResamplingSdReader::playWav(const char *filename) { + return play(filename, true); +} + +bool ResamplingSdReader::play(const char *filename, bool isWave, uint16_t numChannelsIfRaw) +{ + stop(); + //system("echo ${PWD}"); + if (!isWave) // if raw file, then hardcode the numChannels as per the parameter + setNumChannels(numChannelsIfRaw); + + if (_sourceBuffer) { + //Serial.printf("closing %s\n", _filename); + __disable_irq(); + _sourceBuffer->close(); + __enable_irq(); + } + if (_sourceBuffer) delete _sourceBuffer; + if (_filename) delete [] _filename; + _filename = new char[strlen(filename)+1] {0}; + memcpy(_filename, filename, strlen(filename) + 1); + StartUsingSPI(); + + __disable_irq(); + File file = SD.open(_filename); + __enable_irq(); + + if (!file) { + StopUsingSPI(); + Serial.printf("Not able to open file: %s\n", _filename); + if (_filename) delete [] _filename; + _filename = nullptr; + return false; + } + + __disable_irq(); + _file_size = file.size(); + __enable_irq(); + + if (isWave) { + wav_header wav_header; + wav_data_header data_header; + + WaveHeaderParser wavHeaderParser; + char buffer[36]; + __disable_irq(); + size_t bytesRead = file.read(buffer, 36); + + __enable_irq(); + wavHeaderParser.readWaveHeaderFromBuffer((const char *) buffer, wav_header); + if (wav_header.bit_depth != 16) { + Serial.printf("Needs 16 bit audio! Aborting.... (got %d)", wav_header.bit_depth); + return false; + } + setNumChannels(wav_header.num_channels); + + bytesRead = file.read(buffer, 8); + unsigned infoTagsSize; + if (!wavHeaderParser.readInfoTags((unsigned char *)buffer, 0, infoTagsSize)) + { + Serial.println("Not able to read header! Aborting..."); + return false; + } + + file.seek(36 + infoTagsSize); + bytesRead = file.read(buffer, 8); + + if (!wavHeaderParser.readDataHeader((unsigned char *)buffer, 0, data_header)) { + Serial.println("Not able to read header! Aborting..."); + return false; + } + + _header_offset = (44 + infoTagsSize) / 2; + _loop_finish = ((data_header.data_bytes) / 2) + _header_offset; + } else + _loop_finish = _file_size / 2; + + __disable_irq(); + file.close(); + __enable_irq(); + + _sourceBuffer = new newdigate::IndexableFile<128, 2>(_filename); + _loop_start = _header_offset; + if (_file_size <= _header_offset * newdigate::IndexableFile<128, 2>::element_size) { + _playing = false; + if (_filename) delete [] _filename; + _filename = nullptr; + Serial.printf("Wave file contains no samples: %s\n", filename); + return false; + } + + reset(); + _playing = true; + return true; +} + +bool ResamplingSdReader::play() +{ + stop(); + reset(); + _playing = true; + return true; +} + +void ResamplingSdReader::reset(){ + initializeInterpolationPoints(); + if (_playbackRate > 0.0) { + // forward playabck - set _file_offset to first audio block in file + _bufferPosition = _header_offset; + } else { + // reverse playback - forward _file_offset to last audio block in file + _bufferPosition = _loop_finish / _numChannels - _numChannels; + } +} + +void ResamplingSdReader::stop() +{ + if (_playing) { + __disable_irq(); + _playing = false; + //_file.close(); + __enable_irq(); + //StopUsingSPI(); + } +} + +int ResamplingSdReader::available(void) { + return _playing; +} + +void ResamplingSdReader::close(void) { + if (_playing) + stop(); + if (_sourceBuffer) { + _sourceBuffer->close(); + delete _sourceBuffer; + } + StopUsingSPI(); + _sourceBuffer = nullptr; + //TODO: dispose _sourceBuffer properly + deleteInterpolationPoints(); +} \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/src/ResamplingSdReader.h b/third-party/TeensyVariablePlayback/src/ResamplingSdReader.h new file mode 100644 index 0000000..909113c --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/ResamplingSdReader.h @@ -0,0 +1,144 @@ +// +// Created by Nicholas Newdigate on 10/02/2019. +// + +#ifndef TEENSYAUDIOLIBRARY_RESAMPLINGSDREADER_H +#define TEENSYAUDIOLIBRARY_RESAMPLINGSDREADER_H + +#include "SD.h" +#include +#include "spi_interrupt.h" +#include "loop_type.h" +#include "interpolation.h" +#include "IndexableFile.h" + +#define RESAMPLE_BUFFER_SAMPLE_SIZE 128 + +class ResamplingSdReader { +public: + ResamplingSdReader() { + } + + void begin(void); + bool playRaw(const char *filename, uint16_t numChannels); + bool playWav(const char *filename); + + bool play(); + void stop(void); + bool isPlaying(void) { return _playing; } + + unsigned int read(void **buf, uint16_t nbyte); + bool readNextValue(int16_t *value, uint16_t channelNumber); + + void setPlaybackRate(double f) { + _playbackRate = f; + if (f < 0.0 && _bufferPosition == 0) { + //_file.seek(_file_size); + _bufferPosition = _file_size / 2 - _numChannels; + } + } + + double playbackRate() { + return _playbackRate; + } + + void setLoopType(loop_type loopType) + { + _loopType = loopType; + } + + loop_type getLoopType(){ + return _loopType; + } + + int available(void); + void reset(void); + void close(void); + + void setLoopStart(uint32_t loop_start) { + _loop_start = _header_offset + (loop_start * _numChannels); + } + + void setLoopFinish(uint32_t loop_finish) { + // sample number, (NOT byte number) + _loop_finish = _header_offset + (loop_finish * _numChannels); + } + + void setInterpolationType(ResampleInterpolationType interpolationType) { + if (interpolationType != _interpolationType) { + _interpolationType = interpolationType; + initializeInterpolationPoints(); + } + } + + int16_t getNumChannels() { + return _numChannels; + } + + void setNumChannels(uint16_t numChannels) { + if (numChannels != _numChannels) { + _numChannels = numChannels; + initializeInterpolationPoints(); + } + } + + void setHeaderSize(uint32_t headerSizeInBytes) { + _header_offset = headerSizeInBytes / 2; + if (_bufferPosition < _header_offset) { + if (_playbackRate >= 0) { + _bufferPosition = _header_offset; + } + } + } + +private: + volatile bool _playing = false; + + int32_t _file_size; + int32_t _header_offset = 0; // == (header size in bytes ) / 2 + + double _playbackRate = 1.0; + double _remainder = 0.0; + loop_type _loopType = looptype_none; + int _bufferPosition = 0; + int32_t _loop_start = 0; + int32_t _loop_finish = 0; + int16_t _numChannels = -1; + uint16_t _numInterpolationPointsChannels = 0; + char *_filename = nullptr; + newdigate::IndexableFile<128, 2> *_sourceBuffer = nullptr; + + ResampleInterpolationType _interpolationType = ResampleInterpolationType::resampleinterpolation_none; + unsigned int _numInterpolationPoints = 0; + InterpolationData **_interpolationPoints = nullptr; + + static bool isUsingSPI; + void StartUsingSPI(){ + if (!isUsingSPI) { + isUsingSPI = true; +#if defined(HAS_KINETIS_SDHC) + if (!(SIM_SCGC3 & SIM_SCGC3_SDHC)) AudioStartUsingSPI(); +#else + AudioStartUsingSPI(); +#endif + } + } + + void StopUsingSPI() { + if (isUsingSPI) { + isUsingSPI = false; +#if defined(HAS_KINETIS_SDHC) + if (!(SIM_SCGC3 & SIM_SCGC3_SDHC)) AudioStopUsingSPI(); +#else + AudioStopUsingSPI(); +#endif + } + } + + bool play(const char *filename, bool isWave, uint16_t numChannelsIfRaw = 0); + void initializeInterpolationPoints(void); + void deleteInterpolationPoints(void); +}; + + +#endif //TEENSYAUDIOLIBRARY_RESAMPLINGSDREADER_H diff --git a/third-party/TeensyVariablePlayback/src/TeensyVariablePlayback.h b/third-party/TeensyVariablePlayback/src/TeensyVariablePlayback.h new file mode 100644 index 0000000..75c53a3 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/TeensyVariablePlayback.h @@ -0,0 +1,14 @@ +// +// Created by Nicholas Newdigate on 21/07/2020. +// + +#ifndef TEENSY_RESAMPLING_ARDUINO_SAMPLER_H +#define TEENSY_RESAMPLING_ARDUINO_SAMPLER_H + +#include "waveheaderparser.h" +#include "ResamplingSdReader.h" +#include "ResamplingArrayReader.h" +#include "playsdresmp.h" +#include "playarrayresmp.h" + +#endif //TEENSY_RESAMPLING_ARDUINO_SAMPLER_H diff --git a/third-party/TeensyVariablePlayback/src/interpolation.cpp b/third-party/TeensyVariablePlayback/src/interpolation.cpp new file mode 100644 index 0000000..fff75f5 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/interpolation.cpp @@ -0,0 +1,56 @@ +// +// Created by Nicholas Newdigate on 24/05/2021. +// +#include "interpolation.h" + +// https://en.wikipedia.org/wiki/Lagrange_polynomial +// https://www.geeksforgeeks.org/lagranges-interpolation/ +// function to interpolate the given data points using Lagrange's formula +// xi corresponds to the new data point whose value is to be obtained +// n represents the number of known data points +int16_t interpolate(InterpolationData *f, double xi, int n) { + double result = 0.0; // Initialize result + for (int i=0; i 32767) + return 32767; + return untruncated; +} + + +int16_t fastinterpolate(int16_t d1, int16_t d2, int16_t d3, int16_t d4, float x) { + float x_1 = x * 1000.0; + float x_2 = x_1 * x_1; + float x_3 = x_2 * x_1; + + //Serial.printf("%i,%i,%i,%i @ x=%f \n", d1,d2,d3,d4,x); + + return d1 * (x_3 - 6000 * x_2 + 11000000 * x_1 - 6000000000 ) / - 6000000000 + + d2 * (x_3 - 5000 * x_2 + 6000000 * x_1 ) / 2000000000 + + d3 * (x_3 - 4000 * x_2 + 3000000 * x_1 ) / - 2000000000 + + d4 * (x_3 - 3000 * x_2 + 2000000 * x_1 ) / 6000000000; + +/* + int32_t untruncated = result; + if (untruncated < -32768) + return -32768; + if (untruncated > 32767) + return 32767; + return result; + */ +} \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/src/interpolation.h b/third-party/TeensyVariablePlayback/src/interpolation.h new file mode 100644 index 0000000..fcb46e6 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/interpolation.h @@ -0,0 +1,29 @@ +// +// Created by Nicholas Newdigate on 24/05/2021. +// +#ifndef TEENSY_RESAMPLING_SDREADER_INTERPOLATION_H +#define TEENSY_RESAMPLING_SDREADER_INTERPOLATION_H + +#include +#include + + +enum ResampleInterpolationType { + resampleinterpolation_none = 1, + resampleinterpolation_linear = 2, + resampleinterpolation_quadratic = 3, +}; + +struct InterpolationData +{ + int16_t x, y; +}; + +// https://en.wikipedia.org/wiki/Lagrange_polynomial +// https://www.geeksforgeeks.org/lagranges-interpolation/ +// function to interpolate the given data points using Lagrange's formula +// xi corresponds to the new data point whose value is to be obtained +// n represents the number of known data points +int16_t interpolate(InterpolationData *f, double xi, int n); +int16_t fastinterpolate(int16_t d1, int16_t d2, int16_t d3, int16_t d4, float x); +#endif //TEENSY_RESAMPLING_SDREADER_INTERPOLATION_H diff --git a/third-party/TeensyVariablePlayback/src/loop_type.h b/third-party/TeensyVariablePlayback/src/loop_type.h new file mode 100644 index 0000000..bd22ec5 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/loop_type.h @@ -0,0 +1,14 @@ +// +// Created by Nicholas Newdigate on 25/04/2021. +// + +#ifndef TEENSY_RESAMPLING_LOOP_TYPE_H +#define TEENSY_RESAMPLING_LOOP_TYPE_H + +typedef enum loop_type { + looptype_none, + looptype_repeat, + looptype_pingpong +} loop_type; + +#endif //TEENSY_RESAMPLING_LOOP_TYPE_H diff --git a/third-party/TeensyVariablePlayback/src/playarrayresmp.cpp b/third-party/TeensyVariablePlayback/src/playarrayresmp.cpp new file mode 100644 index 0000000..a214e61 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/playarrayresmp.cpp @@ -0,0 +1,92 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#include "playarrayresmp.h" + +void AudioPlayArrayResmp::begin() +{ + file_size = 0; + arrayReader.begin(); +} + +bool AudioPlayArrayResmp::playRaw(int16_t *data, uint32_t numSamples, uint16_t numChannels) +{ + stop(); + bool playing = arrayReader.playRaw(data, numSamples, numChannels); + return playing; +} + +bool AudioPlayArrayResmp::playRaw(const unsigned int *data, uint32_t numSamples, uint16_t numChannels) +{ + return playRaw((int16_t *) data, numSamples, numChannels); +} + +bool AudioPlayArrayResmp::playWav(int16_t *data, uint32_t fileSize) +{ + stop(); + bool playing = arrayReader.playWav(data, fileSize); + + return playing; +} + +bool AudioPlayArrayResmp::playWav(const unsigned int *data, uint32_t fileSize) { + return playWav((int16_t *) data, fileSize); +} + +void AudioPlayArrayResmp::stop() +{ + arrayReader.stop(); +} + +void AudioPlayArrayResmp::update() +{ + int _numChannels = arrayReader.getNumChannels(); + if (_numChannels == -1) + return; + + unsigned int i, n; + audio_block_t *blocks[_numChannels]; + int16_t *data[_numChannels]; + // only update if we're playing + if (!arrayReader.isPlaying()) return; + + // allocate the audio blocks to transmit + for (int i=0; i < _numChannels; i++) { + blocks[i] = allocate(); + if (blocks[i] == nullptr) return; + data[i] = blocks[i]->data; + } + + if (arrayReader.available()) { + // we can read more data from the file... + n = arrayReader.read((void**)data, AUDIO_BLOCK_SAMPLES); + for (int channel=0; channel < _numChannels; channel++) { + for (i=n; i < AUDIO_BLOCK_SAMPLES; i++) { + blocks[channel]->data[i] = 0; + } + transmit(blocks[channel], channel); + } + + if(_numChannels == 1) { + transmit(blocks[0], 1); + } + } else { + arrayReader.close(); + } + for (int channel=0; channel < _numChannels; channel++) { + release(blocks[channel]); + } +} + +#define B2M (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT / 2.0) // 97352592 + +uint32_t AudioPlayArrayResmp::positionMillis() +{ + return ((uint64_t)file_size * B2M) >> 32; +} + +uint32_t AudioPlayArrayResmp::lengthMillis() +{ + return ((uint64_t)file_size * B2M) >> 32; +} \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/src/playarrayresmp.h b/third-party/TeensyVariablePlayback/src/playarrayresmp.h new file mode 100644 index 0000000..6a11c4c --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/playarrayresmp.h @@ -0,0 +1,71 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_PLAYARRAYRESMP_H +#define TEENSY_RESAMPLING_SDREADER_PLAYARRAYRESMP_H + + +#include "Arduino.h" +#include "AudioStream.h" +#include "ResamplingArrayReader.h" +#include "playresmp.h" + +class AudioPlayArrayResmp : public AudioPlayResmp +{ +public: + AudioPlayArrayResmp(void) : + AudioPlayResmp(), + arrayReader() + { + begin(); + } + + void begin(void); + bool playRaw(int16_t *data, uint32_t numSamples, uint16_t numChannels); + bool playRaw(const unsigned int *data, uint32_t numSamples, uint16_t numChannels); + + bool playWav(int16_t *data, uint32_t fileSize); + bool playWav(const unsigned int *data, uint32_t fileSize); + + void stop(void); + bool isPlaying(void) { return arrayReader.isPlaying(); } + uint32_t positionMillis(void); + uint32_t lengthMillis(void); + virtual void update(void); + + void setPlaybackRate(float f) { + arrayReader.setPlaybackRate(f); + } + + void setLoopType(loop_type t) { + arrayReader.setLoopType(t); + } + + void startLoop(uint32_t samples) { + arrayReader.loop(samples); + } + + void setLoopStart(uint32_t loop_start) { + arrayReader.setLoopStart(loop_start); + } + + void setLoopFinish(uint32_t loop_finish) { + arrayReader.setLoopFinish(loop_finish); + } + + void enableInterpolation(bool enable) { + if (enable) + arrayReader.setInterpolationType(ResampleInterpolationType::resampleinterpolation_quadratic); + else + arrayReader.setInterpolationType(ResampleInterpolationType::resampleinterpolation_none); + } +private: + + uint32_t file_size; + ResamplingArrayReader arrayReader; + +}; + + +#endif //TEENSY_RESAMPLING_SDREADER_PLAYARRAYRESMP_H diff --git a/third-party/TeensyVariablePlayback/src/playresmp.h b/third-party/TeensyVariablePlayback/src/playresmp.h new file mode 100644 index 0000000..3d0ad3f --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/playresmp.h @@ -0,0 +1,24 @@ +#ifndef TEENSY_RESAMPLING_SDREADER_PLAYRESMP_H +#define TEENSY_RESAMPLING_SDREADER_PLAYRESMP_H + +#include "Arduino.h" +#include "Audio.h" +#include "loop_type.h" + +class AudioPlayResmp : public AudioStream +{ + public: + AudioPlayResmp(void): AudioStream(0, NULL) {} + virtual ~AudioPlayResmp() {} + + virtual void setPlaybackRate(float f) = 0; + virtual void setLoopType(loop_type t) = 0; + virtual void setLoopStart(uint32_t loop_start) = 0; + virtual void setLoopFinish(uint32_t loop_finish) = 0; + virtual void begin() = 0; + virtual void enableInterpolation(bool enable) = 0; + virtual bool isPlaying(void) = 0; + virtual void stop() = 0; +}; + +#endif // TEENSY_RESAMPLING_SDREADER_PLAYRESMP_H \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/src/playsdresmp.cpp b/third-party/TeensyVariablePlayback/src/playsdresmp.cpp new file mode 100644 index 0000000..bd15b0d --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/playsdresmp.cpp @@ -0,0 +1,85 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#include "playsdresmp.h" +#include "spi_interrupt.h" +#include "waveheaderparser.h" + +void AudioPlaySdResmp::begin() +{ + file_size = 0; + sdReader.begin(); +} + +bool AudioPlaySdResmp::playRaw(const char *filename, uint16_t numChannels) +{ + stop(); + bool playing = sdReader.playRaw(filename, numChannels); + return playing; +} + +bool AudioPlaySdResmp::playWav(const char *filename) +{ + stop(); + bool playing = sdReader.playWav(filename); + return playing; + +} + +void AudioPlaySdResmp::stop() +{ + sdReader.stop(); +} + +void AudioPlaySdResmp::update() +{ + int _numChannels = sdReader.getNumChannels(); + if (_numChannels == -1) + return; + + unsigned int i, n; + audio_block_t *blocks[_numChannels]; + int16_t *data[_numChannels]; + // only update if we're playing + if (!sdReader.isPlaying()) return; + + // allocate the audio blocks to transmit + for (int i=0; i < _numChannels; i++) { + blocks[i] = allocate(); + if (blocks[i] == nullptr) return; + data[i] = blocks[i]->data; + } + + if (sdReader.available()) { + // we can read more data from the file... + n = sdReader.read((void**)data, AUDIO_BLOCK_SAMPLES); + for (int channel=0; channel < _numChannels; channel++) { + for (i=n; i < AUDIO_BLOCK_SAMPLES; i++) { + blocks[channel]->data[i] = 0; + } + transmit(blocks[channel], channel); + } + + if(_numChannels == 1) { + transmit(blocks[0], 1); + } + } else { + sdReader.close(); + } + for (int channel=0; channel < _numChannels; channel++) { + release(blocks[channel]); + } +} + +#define B2M (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT / 2.0) // 97352592 + +uint32_t AudioPlaySdResmp::positionMillis() +{ + return ((uint64_t)file_size * B2M) >> 32; +} + +uint32_t AudioPlaySdResmp::lengthMillis() +{ + return ((uint64_t)file_size * B2M) >> 32; +} \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/src/playsdresmp.h b/third-party/TeensyVariablePlayback/src/playsdresmp.h new file mode 100644 index 0000000..d4ae427 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/playsdresmp.h @@ -0,0 +1,65 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_PLAYSDRAWRESMP_H +#define TEENSY_RESAMPLING_SDREADER_PLAYSDRAWRESMP_H + + +#include "Arduino.h" +#include "AudioStream.h" +#include "SD.h" +#include "stdint.h" +#include "ResamplingSdReader.h" +#include "playresmp.h" + +class AudioPlaySdResmp : public AudioPlayResmp +{ +public: + AudioPlaySdResmp(void) : + AudioPlayResmp(), + sdReader() + { + begin(); + } + + void begin(void); + bool playRaw(const char *filename, uint16_t numChannels); + bool playWav(const char *filename); + void stop(void); + bool isPlaying(void) { return sdReader.isPlaying(); } + uint32_t positionMillis(void); + uint32_t lengthMillis(void); + virtual void update(void); + + void setPlaybackRate(float f) { + sdReader.setPlaybackRate(f); + } + + void setLoopType(loop_type t) { + sdReader.setLoopType(t); + } + + void setLoopStart(uint32_t loop_start) { + sdReader.setLoopStart(loop_start); + } + + void setLoopFinish(uint32_t loop_finish) { + sdReader.setLoopFinish(loop_finish); + } + + void enableInterpolation(bool enable) { + if (enable) + sdReader.setInterpolationType(ResampleInterpolationType::resampleinterpolation_quadratic); + else + sdReader.setInterpolationType(ResampleInterpolationType::resampleinterpolation_none); + } +private: + + uint32_t file_size; + ResamplingSdReader sdReader; + +}; + + +#endif //TEENSY_RESAMPLING_SDREADER_PLAYSDRAWRESMP_H diff --git a/third-party/TeensyVariablePlayback/src/waveheaderparser.h b/third-party/TeensyVariablePlayback/src/waveheaderparser.h new file mode 100644 index 0000000..f2678e1 --- /dev/null +++ b/third-party/TeensyVariablePlayback/src/waveheaderparser.h @@ -0,0 +1,185 @@ +// +// Created by Nicholas Newdigate on 20/07/2020. +// +#ifndef TEENSY_RESAMPLING_SDREADER_WAVEHEADERPARSER_H +#define TEENSY_RESAMPLING_SDREADER_WAVEHEADERPARSER_H + +#include +#include +#include +#include "spi_interrupt.h" + +using namespace std; + +// from https://gist.github.com/Jon-Schneider/8b7c53d27a7a13346a643dac9c19d34f +struct wav_header { + // RIFF Header + char riff_header[4]; // 00 - 03 - Contains "RIFF" + int header_chunk_size; // 04 - 07 - Size of the wav portion of the file, which follows the first 8 bytes. File size - 8 + char wave_header[4]; // 08 - 11 - Contains "WAVE" + + // Format Header + char fmt_header[4]; // 12 - 15 - Contains "fmt " (includes trailing space) + int fmt_chunk_size; // 16 - 19 - Should be 16 for PCM + short audio_format; // 20 - 21 - Should be 1 for PCM. 3 for IEEE Float + short num_channels; // 22 - 23 + int sample_rate; // 24 - 27 + int byte_rate; // 28 - 31 + short sample_alignment; // 32 - 33 + short bit_depth; // 34 - 35 +}; + +struct wav_data_header { + // Data + char data_header[4]; // 36 - 39 + unsigned int data_bytes;// 40 - 43 +}; + +class WaveHeaderParser { +public: + bool readWaveHeader(const char *filename, wav_header &header, wav_data_header &wav_data_header) { + __disable_irq(); + File wavFile = SD.open(filename); + __enable_irq(); + if (!wavFile) { + Serial.printf("Not able to open wave file... %s\n", filename); + return false; + } + bool result = readWaveHeader(filename, header, wavFile); + if (result) { + wavFile.seek(36); + unsigned char buffer[8]; + size_t bytesRead = wavFile.read(buffer, 8); + if (bytesRead != 8) { + Serial.printf("Not able to read header... %s\n", filename); + result = false; + } + + if (result) { + unsigned infoTagsSize; + result = readInfoTags(buffer, 0, infoTagsSize); + + if (result) { + wavFile.seek(36 + infoTagsSize); + bytesRead = wavFile.read(buffer, 8); + if (bytesRead != 8) { + Serial.printf("Not able to read header... %s\n", filename); + return false; + } + + result = readDataHeader(buffer, 0, wav_data_header); + } + } + } + wavFile.close(); + return result; + } + + bool readWaveHeader(const char *filename, wav_header &header, File &wavFile) { + char buffer[36]; + __disable_irq(); + int bytesRead = wavFile.read(buffer, 36); + __enable_irq(); + if (bytesRead != 36) { + Serial.printf("expected 36 bytes (was %d)\n", bytesRead); + return false; + } + return readWaveHeaderFromBuffer(buffer, header); + } + + bool readWaveHeaderFromBuffer(const char *buffer, wav_header &header) { + if (buffer[0] != 'R' || buffer[1] != 'I' || buffer[2] != 'F' || buffer[3] != 'F') { + Serial.printf("expected RIFF (was %s)\n", buffer); + return false; + } + for (int i=0; i < 4; i++) + header.riff_header[i] = buffer[i]; + + unsigned char *b = (unsigned char*)buffer; + + auto header_chunk_size = static_cast(b[7] << 24 | b[6] << 16 | b[5] << 8 | b[4]); + header.header_chunk_size = header_chunk_size; + + for (int i=0; i < 4; i++) + header.wave_header[i] = buffer[i+8]; + if (buffer[8] != 'W' || buffer[9] != 'A' || buffer[10] != 'V' || buffer[11] != 'E') { + Serial.printf("expected WAVE (was %s)\n", buffer[8]); + return false; + } + + for (int i=0; i < 4; i++) + header.fmt_header[i] = buffer[i+12]; + if (buffer[12] != 'f' || buffer[13] != 'm' || buffer[14] != 't' || buffer[15] != ' ') { + Serial.printf("expected 'fmt ' (was %s)\n", buffer[12]); + return false; + } + + auto fmt_chunk_size = static_cast(b[19] << 24 | b[18] << 16 | b[17] << 8 | b[16]); + header.fmt_chunk_size = fmt_chunk_size; + if (fmt_chunk_size != 16) { + Serial.printf("chunk size should be 16 for PCM wave data... (was %d)\n", fmt_chunk_size); + return false; + } + + auto audio_format = static_cast((b[21] << 8) | b[20]); + header.audio_format = audio_format; + + auto num_channels = static_cast((b[23] << 8) | b[22]); + header.num_channels = num_channels; + + uint32_t sample_rate = static_cast(b[27] << 24 | b[26] << 16 | b[25] << 8 | b[24]); + header.sample_rate = sample_rate; + + uint32_t byte_rate = static_cast(b[31] << 24 | b[30] << 16 | b[29] << 8 | b[28]); + header.byte_rate = byte_rate; + + auto sample_alignment = static_cast((b[33] << 8) | b[32]); + header.sample_alignment = sample_alignment; + + auto bit_depth = static_cast(b[35] << 8 | b[34]); + header.bit_depth = bit_depth; + + return true; + } + + bool readInfoTags(unsigned char *buffer, size_t offset, unsigned &infoTagsSize) { + if ( buffer[offset+0] == 'L' + && buffer[offset+1] == 'I' + && buffer[offset+2] == 'S' + && buffer[offset+3] == 'T') { + infoTagsSize = static_cast(buffer[offset+7] << 24 | buffer[offset+6] << 16 | buffer[offset+5] << 8 | buffer[offset+4]); + infoTagsSize += 8; + return true; + } + + if ( buffer[offset+0] == 'd' + && buffer[offset+1] == 'a' + && buffer[offset+2] == 't' + && buffer[offset+3] == 'a') { + infoTagsSize = 0; + return true; + } + + Serial.println("expected 'data' or 'LIST'..."); + return false; + } + + bool readDataHeader(unsigned char *buffer, size_t offset, wav_data_header &data_header) { + + for (int i=0; i < 4; i++) + data_header.data_header[i] = buffer[i+offset]; + + if (buffer[offset+0] != 'd' || buffer[offset+1] != 'a' || buffer[offset+2] != 't' || buffer[offset+3] != 'a') { + Serial.printf("expected data... (was %d)\n", buffer); + return false; + } + + auto data_bytes = static_cast(buffer[offset+7] << 24 | buffer[offset+6] << 16 | buffer[offset+5] << 8 | buffer[offset+4]); + data_header.data_bytes = data_bytes; + return true; + } +private: +}; + + +#endif //TEENSY_RESAMPLING_SDREADER_WAVEHEADERPARSER_H diff --git a/third-party/TeensyVariablePlayback/test.sh b/third-party/TeensyVariablePlayback/test.sh new file mode 100644 index 0000000..b31b446 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cd cmake-build-debug/test/ +./tests diff --git a/third-party/TeensyVariablePlayback/test/CMakeLists.txt b/third-party/TeensyVariablePlayback/test/CMakeLists.txt new file mode 100644 index 0000000..74b6efc --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/CMakeLists.txt @@ -0,0 +1,87 @@ +cmake_minimum_required(VERSION 3.5) +project(tests C CXX) +if (DEFINED BUILD_FOR_LINUX) + set(CMAKE_CXX_STANDARD 17) + + set (Boost_USE_STATIC_LIBS OFF) + find_package (Boost REQUIRED COMPONENTS unit_test_framework) + include_directories (${Boost_INCLUDE_DIRS}) + + find_package(teensy_x86_stubs) + include_directories(${teensy_x86_stubs_INCLUDE_DIR}) + message(STATUS "include-dir: teensy_x86_stubs: ${teensy_x86_stubs_INCLUDE_DIR}") + + find_package(teensy_audio_x86_stubs) + include_directories(${teensy_audio_x86_stubs_INCLUDE_DIR}) + + find_package(teensy_x86_sd_stubs) + include_directories(${teensy_x86_sd_stubs_INCLUDE_DIR}) + + include_directories(../src) + include_directories(../test/audio) + + add_executable(embedfile embedfile.c) + + add_custom_command(OUTPUT kick_raw.c + COMMAND embedfile kick_raw ${CMAKE_SOURCE_DIR}/test/resources/input/kick.raw + ) + + add_custom_command(OUTPUT stereo_souljah_raw.c + COMMAND embedfile stereo_souljah_raw ${CMAKE_SOURCE_DIR}/test/resources/input/stereo_souljah.raw + ) + + add_custom_command(OUTPUT stereo_souljah_wav.c + COMMAND embedfile stereo_souljah_wav ${CMAKE_SOURCE_DIR}/test/resources/input/stereo_souljah.wav + ) + + add_custom_command(OUTPUT mono_souljah_wav.c + COMMAND embedfile mono_souljah_wav ${CMAKE_SOURCE_DIR}/test/resources/input/mono_souljah.wav + ) + + add_custom_command(OUTPUT PNO1C1_raw.c + COMMAND embedfile PNO1C1_raw ${CMAKE_SOURCE_DIR}/test/resources/input/PNO1C1.raw + ) + + add_executable(tests + kick_raw.c + stereo_souljah_raw.c + stereo_souljah_wav.c + mono_souljah_wav.c + PNO1C1_raw.c + audio/output_test.cpp + + audio/array/AudioArrayFixture.h + audio/array/test_array_mono_loop_forward_playback.cpp + audio/array/test_array_stereo_loop_forward_playback.cpp + + audio/wav/AudioWavFixture.h + audio/wav/test_wav_mono_loop_forward_playback.cpp + audio/wav/test_wav_stereo_loop_forward_playback.cpp + audio/wav/test_wav_tags.cpp + + low_level/sd/ResamplingReaderFixture.h + low_level/sd/test_raw_mono_noloop_forward_playback.cpp + low_level/sd/test_raw_mono_noloop_forward_double_rate_playback.cpp + low_level/sd/test_raw_mono_loop_forward_playback.cpp + low_level/sd/test_wav_mono_noloop_forward_playback.cpp + low_level/sd/test_wav_mono_loop_forward_playback.cpp + low_level/sd/test_wav_mono_noloop_backward_playback.cpp + + low_level/wav_header/test_parse_wave_header.cpp + + low_level/array/test_array_mono_loop_forward_playback.cpp + low_level/array/test_array_stereo_loop_forward_playback.cpp + + low_level/arraywav/test_array_mono_loop_forward_playback.cpp + low_level/arraywav/test_array_stereo_loop_forward_playback.cpp + + low_level/indexedfile/test_indexablefile.cpp + ) + + target_link_libraries(tests ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + target_link_libraries(tests ${teensy_x86_stubs_LIBS}) + target_link_libraries(tests ${teensy_audio_x86_stubs_LIBS}) + target_link_libraries(tests ${teensy_x86_sd_stubs_LIBS}) + target_link_libraries(tests teensy_variable_playback) + message(STATUS ${teensy_x86_stubs_LIBS}) +endif() \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/test/audio/array/AudioArrayFixture.h b/third-party/TeensyVariablePlayback/test/audio/array/AudioArrayFixture.h new file mode 100644 index 0000000..5a38de9 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/array/AudioArrayFixture.h @@ -0,0 +1,24 @@ +// +// Created by Nicholas Newdigate on 17/06/2021. +// +#ifndef TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYFIXTURE_H +#define TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYFIXTURE_H + +#include +#include +#include +#include "output_test.h" +#include "playarrayresmp.h" + +struct AudioArrayFixture { + + AudioArrayFixture() { + AudioMemory(20); + } + + ~AudioArrayFixture() { + arduino_should_exit = true; + } +}; + +#endif //TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYFIXTURE_H diff --git a/third-party/TeensyVariablePlayback/test/audio/array/test_array_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/audio/array/test_array_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..0428821 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/array/test_array_mono_loop_forward_playback.cpp @@ -0,0 +1,234 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_AUDIO_ARRAY_READERTESTS_CPP +#define TEENSY_AUDIO_ARRAY_READERTESTS_CPP + +#include +#include "AudioArrayFixture.h" + +extern unsigned char kick_raw[]; +extern unsigned int kick_raw_len; // in bytes, divide by 2 to get samples + +BOOST_AUTO_TEST_SUITE(test_audio_array_mono_loop_forward_playback) + + const uint16_t numberOfChannels = 1; + + const std::string referencePath = "test/resources/reference/"; + const std::string inputPath = "test/resources/input/"; + const std::string outputPath = "output/"; + + BOOST_FIXTURE_TEST_CASE(Array_fwd_1_0000_quadratic_mono_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + // GUItool: end automatically generated code + + const double playbackRate = 1.0; + const std::string testName = "Array_fwd_1_0000_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)kick_raw, kick_raw_len / 2, numberOfChannels); + for (int i=0; i < ((kick_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_0_5000_quadratic_mono_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + // GUItool: end automatically generated code + const double playbackRate = 0.5; + const std::string testName = "Array_fwd_0_5000_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)kick_raw, kick_raw_len / 2, numberOfChannels); + for (int i=0; i < ((kick_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_2_0000_quadratic_mono_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + // GUItool: end automatically generated code + + const double playbackRate = 2.0; + const std::string testName = "Array_fwd_2_0000_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)kick_raw, kick_raw_len / 2, numberOfChannels); + for (int i=0; i < ((kick_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_0_7437_quadratic_mono_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + // GUItool: end automatically generated code + + const double playbackRate = 0.7437; + const std::string testName = "Array_fwd_0_7437_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)kick_raw, kick_raw_len / 2, numberOfChannels); + for (int i=0; i < ((kick_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_1_7437_quadratic_mono_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + // GUItool: end automatically generated code + + const double playbackRate = 1.7437; + const std::string testName = "Array_fwd_1_7437_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)kick_raw, kick_raw_len / 2, numberOfChannels); + for (int i=0; i < ((kick_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_8_7437_quadratic_mono_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + // GUItool: end automatically generated code + + const double playbackRate = 8.7437; + const std::string testName = "Array_fwd_8_7437_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)kick_raw, kick_raw_len / 2, numberOfChannels); + for (int i=0; i < ((kick_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_AUDIO_ARRAY_READERTESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/audio/array/test_array_stereo_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/audio/array/test_array_stereo_loop_forward_playback.cpp new file mode 100644 index 0000000..f0e83fc --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/array/test_array_stereo_loop_forward_playback.cpp @@ -0,0 +1,239 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_AUDIO_ARRAY_READERTESTS_CPP +#define TEENSY_AUDIO_ARRAY_READERTESTS_CPP + +#include +#include "AudioArrayFixture.h" + +extern unsigned char stereo_souljah_raw[]; +extern unsigned int stereo_souljah_raw_len; + +BOOST_AUTO_TEST_SUITE(test_audio_array_stereo_loop_forward_playback) + + const uint16_t numberOfChannels = 2; + const std::string referencePath = "test/resources/reference/"; + const std::string inputPath = "test/resources/input/"; + const std::string outputPath = "output/"; + + BOOST_FIXTURE_TEST_CASE(Array_fwd_1_0000_quadratic_stereo_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + AudioConnection patchCord2(memory, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 1.0; + const std::string testName = "Array_fwd_1_0000_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)stereo_souljah_raw, stereo_souljah_raw_len / 2, numberOfChannels); + for (int i=0; i < ((stereo_souljah_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_0_5000_quadratic_stereo_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + AudioConnection patchCord2(memory, 1, testout, 1); + // GUItool: end automatically generated code + const double playbackRate = 0.5; + const std::string testName = "Array_fwd_0_5000_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)stereo_souljah_raw, stereo_souljah_raw_len / 2, numberOfChannels); + for (int i=0; i < ((stereo_souljah_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_2_0000_quadratic_stereo_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + AudioConnection patchCord2(memory, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 2.0; + const std::string testName = "Array_fwd_2_0000_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)stereo_souljah_raw, stereo_souljah_raw_len / 2, numberOfChannels); + for (int i=0; i < ((stereo_souljah_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_0_7437_quadratic_stereo_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + AudioConnection patchCord2(memory, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 0.7437; + const std::string testName = "Array_fwd_0_7437_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)stereo_souljah_raw, stereo_souljah_raw_len / 2, numberOfChannels); + for (int i=0; i < ((stereo_souljah_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_1_7437_quadratic_stereo_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + AudioConnection patchCord2(memory, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 1.7437; + const std::string testName = "Array_fwd_1_7437_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)stereo_souljah_raw, stereo_souljah_raw_len / 2, numberOfChannels); + for (int i=0; i < ((stereo_souljah_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_8_7437_quadratic_stereo_noloop, AudioArrayFixture) { + + // GUItool: begin automatically generated code + AudioPlayArrayResmp memory; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(memory, 0, testout, 0); + AudioConnection patchCord2(memory, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 8.7437; + const std::string testName = "Array_fwd_8_7437_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath+testName+".wav"; + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + memory.begin(); + memory.enableInterpolation(true); + memory.setPlaybackRate(playbackRate); + memory.playRaw((int16_t*)stereo_souljah_raw, stereo_souljah_raw_len / 2, numberOfChannels); + for (int i=0; i < ((stereo_souljah_raw_len)/128) + 20; i++) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_AUDIO_ARRAY_READERTESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/audio/output_test.cpp b/third-party/TeensyVariablePlayback/test/audio/output_test.cpp new file mode 100644 index 0000000..0170502 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/output_test.cpp @@ -0,0 +1,92 @@ +#include "output_test.h" + +audio_block_t * TestAudioOutput::block_left_1st = NULL; +audio_block_t * TestAudioOutput::block_right_1st = NULL; +bool TestAudioOutput::update_responsibility = false; + +void TestAudioOutput::begin(void) +{ + update_responsibility = update_setup(); + active = true; +} + +void TestAudioOutput::isr(void) +{ + if (TestAudioOutput::update_responsibility) AudioStream::update_all(); +} + +void TestAudioOutput::update(void) +{ + // null audio device: discard all incoming data + if (!active) return; + audio_block_t *block = receiveReadOnly(0); + audio_block_t *blockRight = receiveReadOnly(1); + if (block) { + + if (_saveToFile) { + if (!blockRight){ + _outputFile.write((char*)block->data, 256); + _dataSize += 256; + } else { + + int16_t interleaved[256]; + + if (blockRight) { + memcpy_tdm_tx(interleaved, block->data, blockRight->data); + } else + memset(interleaved, 0, 512); + + _outputFile.write((char*)interleaved, 512); + _dataSize += 512; + } + + } + + /* + Serial.print("Ch1:"); + for (int i=0; idata[i] < 0) + Serial.printf("-%04x ", -block->data[i]); + else + Serial.printf(" %04x ", block->data[i]); + } + Serial.println(); + */ + release(block); + + if (blockRight) { + /* + Serial.print("Ch2:"); + for (int i=0; idata[i] < 0) + Serial.printf("-%04x ", -blockRight->data[i]); + else + Serial.printf(" %04x ", blockRight->data[i]); + } + Serial.println(); + */ + release(blockRight); + } + } else { + //Serial.print(" empty block \n"); + } +} + +// Taken from https://github.com/PaulStoffregen/Audio/blob/master/output_tdm.cpp +void TestAudioOutput::memcpy_tdm_tx(int16_t *dest, int16_t *src1, int16_t *src2) +{ + int16_t i, in1, in2, out1, out2; + + for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) { + *dest = *src1++; + *(dest + 1) = *src2++; + dest += 2; + } +} + +unsigned char TestAudioOutput::test_output_wav_header[] = { + 0x52, 0x49, 0x46, 0x46, 0x38, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, + 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, + 0x64, 0x61, 0x74, 0x61, 0x14, 0x00, 0x00, 0x00 +}; diff --git a/third-party/TeensyVariablePlayback/test/audio/output_test.h b/third-party/TeensyVariablePlayback/test/audio/output_test.h new file mode 100644 index 0000000..f6f9745 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/output_test.h @@ -0,0 +1,101 @@ +#ifndef output_test_h_ +#define output_test_h_ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#define __filesystem std::__fs::filesystem +#else +#define __filesystem std::filesystem +#endif +class TestAudioOutput : public AudioStream +{ +public: + TestAudioOutput(void) : AudioStream(2, inputQueueArray) { begin(); } + virtual void update(void); + void begin(void); + static void isr(void); + bool saveOutputFile(const char * path, const char* filename){ + if (num_inputs == 0) return false; + char cwd[500]; + if (getcwd(cwd, sizeof(cwd)) != NULL) { + printf("Current working dir: %s\n", cwd); + } else { + perror("getcwd() error"); + } + string outputPath = string(cwd) + "/" + string(path); + __filesystem::path p(outputPath); + if (! __filesystem::exists(p) ) + __filesystem::create_directories(outputPath); + + _filePath = outputPath + string(filename); + std::cout << "saving output audio .wav file to " << _filePath << std::endl; + _outputFile.open(_filePath, ios_base::trunc | ios_base::out); + if (!_outputFile.is_open()) { + Serial.printf("couldn't open file for recording...%s\n", _filePath.c_str()); + return false; + } else { + _filename = filename; + _outputFile.write((char*)test_output_wav_header, 44); + _saveToFile = true; + return true; + } + } + void closeOutputfile(uint16_t numChannels) { + if (!_saveToFile) return; + if (_outputFile.is_open()) { + _saveToFile = false; + char buf[4]; + buf[1] = numChannels >> 8; + buf[0] = numChannels; + _outputFile.seekp(22, ios_base::beg); + _outputFile.write(buf, 2); + + long bytespersecond = numChannels * 2 * 44100; + buf[3] = bytespersecond >> 24; + buf[2] = bytespersecond >> 16; + buf[1] = bytespersecond >> 8; + buf[0] = bytespersecond; + _outputFile.seekp(28, ios_base::beg); + _outputFile.write(buf, 4); + + short bytespersampleframe = numChannels * 2; + buf[1] = bytespersampleframe >> 8; + buf[0] = bytespersampleframe; + _outputFile.seekp(32, ios_base::beg); + _outputFile.write(buf, 2); + + buf[3] = _dataSize >> 24; + buf[2] = _dataSize >> 16; + buf[1] = _dataSize >> 8; + buf[0] = _dataSize; + _outputFile.seekp(40, ios_base::beg); + _outputFile.write(buf, 4); + _outputFile.close(); + _filename = nullptr; + } + } +protected: + std::ofstream _outputFile; + std::string _filePath; + static audio_block_t *block_left_1st; + static audio_block_t *block_right_1st; + static bool update_responsibility; + bool _saveToFile = false; + unsigned int _dataSize = 0; + const char *_filename; + static void memcpy_tdm_tx(int16_t *dest, int16_t *src1, int16_t *src2); + +private: + audio_block_t *inputQueueArray[2]; + static unsigned char test_output_wav_header[]; +}; + + +#endif diff --git a/third-party/TeensyVariablePlayback/test/audio/wav/AudioWavFixture.h b/third-party/TeensyVariablePlayback/test/audio/wav/AudioWavFixture.h new file mode 100644 index 0000000..2cb5bba --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/wav/AudioWavFixture.h @@ -0,0 +1,25 @@ +// +// Created by Nicholas Newdigate on 17/06/2021. +// +#ifndef TEENSY_RESAMPLING_SDREADER_RESAMPLINGWAVFIXTURE_H +#define TEENSY_RESAMPLING_SDREADER_RESAMPLINGWAVFIXTURE_H + +#include +#include +#include +#include +#include "output_test.h" +#include "playsdresmp.h" + +struct AudioWavFixture { + + AudioWavFixture() { + AudioMemory(20); + } + + ~AudioWavFixture() { + arduino_should_exit = true; + } +}; + +#endif //TEENSY_RESAMPLING_SDREADER_RESAMPLINGWAVFIXTURE_H diff --git a/third-party/TeensyVariablePlayback/test/audio/wav/test_wav_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/audio/wav/test_wav_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..a771dd5 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/wav/test_wav_mono_loop_forward_playback.cpp @@ -0,0 +1,238 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_AUDIO_SDWAV_MONO_READERTESTS_CPP +#define TEENSY_AUDIO_SDWAV_MONO_READERTESTS_CPP + +#include +#include "AudioWavFixture.h" + +BOOST_AUTO_TEST_SUITE(test_audio_wav_mono_loop_forward_playback) + + const uint16_t numberOfChannels = 1; + + const std::string referencePath = "test/resources/reference/"; + const std::string inputPath = "test/resources/input/"; + const std::string outputPath = "output/"; + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_1_0000_quadratic_mono_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + // GUItool: end automatically generated code + + const double playbackRate = 1.0; + const std::string testName = "Wav_fwd_1_0000_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("kick.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_0_5000_quadratic_mono_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + // GUItool: end automatically generated code + const double playbackRate = 0.5; + const std::string testName = "Wav_fwd_0_5000_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("kick.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_2_0000_quadratic_mono_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + // GUItool: end automatically generated code + + const double playbackRate = 2.0; + const std::string testName = "Wav_fwd_2_0000_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("kick.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_0_7437_quadratic_mono_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + // GUItool: end automatically generated code + + const double playbackRate = 0.7437; + const std::string testName = "Wav_fwd_0_7437_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("kick.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + + } + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_1_7437_quadratic_mono_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + // GUItool: end automatically generated code + + const double playbackRate = 1.7437; + const std::string testName = "Wav_fwd_1_7437_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("kick.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_8_7437_quadratic_mono_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + // GUItool: end automatically generated code + + const double playbackRate = 8.7437; + const std::string testName = "Wav_fwd_8_7437_quadratic_mono_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("kick.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_AUDIO_SDWAV_MONO_READERTESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/audio/wav/test_wav_stereo_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/audio/wav/test_wav_stereo_loop_forward_playback.cpp new file mode 100644 index 0000000..fa1738d --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/wav/test_wav_stereo_loop_forward_playback.cpp @@ -0,0 +1,244 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_AUDIO_SDWAV_STEREO_READERTESTS_CPP +#define TEENSY_AUDIO_SDWAV_STEREO_READERTESTS_CPP + +#include +#include "AudioWavFixture.h" + +BOOST_AUTO_TEST_SUITE(test_audio_wav_stereo_loop_forward_playback) + + const uint16_t numberOfChannels = 2; + + const std::string referencePath = "test/resources/reference/"; + const std::string inputPath = "test/resources/input/"; + const std::string outputPath = "output/"; + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_1_0000_quadratic_stereo_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + AudioConnection patchCord2(wave, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 1.0; + const std::string testName = "Wav_fwd_1_0000_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("stereo_souljah.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_0_5000_quadratic_stereo_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + AudioConnection patchCord2(wave, 1, testout, 1); + // GUItool: end automatically generated code + const double playbackRate = 0.5; + const std::string testName = "Wav_fwd_0_5000_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("stereo_souljah.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_2_0000_quadratic_stereo_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + AudioConnection patchCord2(wave, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 2.0; + const std::string testName = "Wav_fwd_2_0000_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("stereo_souljah.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_0_7437_quadratic_stereo_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + AudioConnection patchCord2(wave, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 0.7437; + const std::string testName = "Wav_fwd_0_7437_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("stereo_souljah.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + + } + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_1_7437_quadratic_stereo_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + AudioConnection patchCord2(wave, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 1.7437; + const std::string testName = "Wav_fwd_1_7437_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("stereo_souljah.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + + BOOST_FIXTURE_TEST_CASE(Wav_fwd_8_7437_quadratic_stereo_noloop, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + AudioConnection patchCord2(wave, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 8.7437; + const std::string testName = "Wav_fwd_8_7437_quadratic_stereo_noloop"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + testout.saveOutputFile(outputPath.c_str(), outputFile.c_str()); + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav("stereo_souljah.wav"); + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_AUDIO_SDWAV_STEREO_READERTESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/audio/wav/test_wav_tags.cpp b/third-party/TeensyVariablePlayback/test/audio/wav/test_wav_tags.cpp new file mode 100644 index 0000000..5b9226a --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/wav/test_wav_tags.cpp @@ -0,0 +1,118 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_AUDIO_SDWAV_STEREO_READERTESTS_CPP +#define TEENSY_AUDIO_SDWAV_STEREO_READERTESTS_CPP + +#include +#include "AudioWavFixture.h" + +BOOST_AUTO_TEST_SUITE(test_audio_wav_tags_in_header) + + const uint16_t numberOfChannels = 2; + const std::string referencePath = "test/resources/reference/"; + const std::string inputPath = "test/resources/input/"; + const std::string outputPath = "output/"; + + BOOST_FIXTURE_TEST_CASE(Wav_with_tags_in_header_1, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + AudioConnection patchCord2(wave, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 1.0; + const std::string testName = "SDTEST1"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + if (!testout.saveOutputFile(outputPath.c_str(), outputFile.c_str())) { + std::cout << "not able to save output file..." << std::endl; + BOOST_ERROR("not able to save output file (1)..."); + } + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + bool isPlaying = wave.playWav(outputFile.c_str()); + if (!isPlaying) { + std::cout << "input audio file is not able to play..." << std::endl; + BOOST_ERROR("input audio file is not able to play (1)..."); + } + if (!wave.isPlaying()) { + std::cout << "input audio file is not able to play..." << std::endl; + BOOST_ERROR("input audio file is not able to play (2)..."); + } + + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::cout << "comparing " << outputFileName << " with " << referenceFileName << ";" << std::endl; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + BOOST_FIXTURE_TEST_CASE(Wav_with_tags_in_header_2, AudioWavFixture) { + + // GUItool: begin automatically generated code + AudioPlaySdResmp wave; //xy=306,225 + TestAudioOutput testout; //xy=612,224 + AudioConnection patchCord1(wave, 0, testout, 0); + AudioConnection patchCord2(wave, 1, testout, 1); + // GUItool: end automatically generated code + + const double playbackRate = 1.0; + const std::string testName = "SDTEST2"; + const std::string outputFile = testName+".wav"; + const std::string outputFileName = outputPath + outputFile; + const std::string referenceFileName = referencePath + testName + ".wav"; + SD.setSDCardFolderPath(inputPath); + + if (!testout.saveOutputFile(outputPath.c_str(), outputFile.c_str())) { + std::cout << "not able to save output file..." << std::endl; + BOOST_CHECK(false); + return; + } + wave.begin(); + wave.enableInterpolation(true); + wave.setPlaybackRate(playbackRate); + wave.playWav(outputFile.c_str()); + + if (!wave.isPlaying()) { + std::cout << "input audio file is not able to play..." << std::endl; + BOOST_CHECK(false); + return; + } + + while (wave.isPlaying()) { + testout.isr(); + } + testout.closeOutputfile(numberOfChannels); + patchCord1.disconnect(); + AudioConnection::reset(); + arduino_should_exit = true; + + std::ifstream ifs1(outputFileName); + std::ifstream ifs2(referenceFileName); + std::istream_iterator b1(ifs1), e1; + std::istream_iterator b2(ifs2), e2; + + BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_AUDIO_SDWAV_STEREO_READERTESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/boost-to-junit-xml.xslt b/third-party/TeensyVariablePlayback/test/boost-to-junit-xml.xslt new file mode 100644 index 0000000..bee89f9 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/boost-to-junit-xml.xslt @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + False + + + True + 0 + + + + + + + + + + + + \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/test/embedfile.c b/third-party/TeensyVariablePlayback/test/embedfile.c new file mode 100644 index 0000000..f08244b --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/embedfile.c @@ -0,0 +1,53 @@ +// taken from https://stackoverflow.com/a/11814544/4634140 +#include +#include + +FILE* open_or_exit(const char* fname, const char* mode) +{ + FILE* f = fopen(fname, mode); + if (f == NULL) { + perror(fname); + exit(EXIT_FAILURE); + } + return f; +} + +int main(int argc, char** argv) +{ + if (argc < 3) { + fprintf(stderr, "USAGE: %s {sym} {rsrc}\n\n" + " Creates {sym}.c from the contents of {rsrc}\n", + argv[0]); + return EXIT_FAILURE; + } + + const char* sym = argv[1]; + FILE* in = open_or_exit(argv[2], "r"); + + char symfile[256]; + snprintf(symfile, sizeof(symfile), "%s.c", sym); + + FILE* out = open_or_exit(symfile,"w"); + fprintf(out, "#include \n"); + fprintf(out, "const char %s[] = {\n", sym); + + unsigned char buf[256]; + size_t nread = 0; + size_t linecount = 0; + do { + nread = fread(buf, 1, sizeof(buf), in); + size_t i; + for (i=0; i < nread; i++) { + fprintf(out, "0x%02x, ", buf[i]); + if (++linecount == 10) { fprintf(out, "\n"); linecount = 0; } + } + } while (nread > 0); + if (linecount > 0) fprintf(out, "\n"); + fprintf(out, "};\n"); + fprintf(out, "const size_t %s_len = sizeof(%s);\n\n",sym,sym); + + fclose(in); + fclose(out); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/test/low_level/array/ResamplingArrayFixture.h b/third-party/TeensyVariablePlayback/test/low_level/array/ResamplingArrayFixture.h new file mode 100644 index 0000000..d6df109 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/array/ResamplingArrayFixture.h @@ -0,0 +1,23 @@ +// +// Created by Nicholas Newdigate on 17/06/2021. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYFIXTURE_H +#define TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYFIXTURE_H + +#include "ResamplingArrayReader.h" + +struct ResamplingArrayFixture { + + ResamplingArrayFixture() { + resamplingArrayReader = new ResamplingArrayReader(); + } + + ~ResamplingArrayFixture() { + delete resamplingArrayReader; + } + + ResamplingArrayReader * resamplingArrayReader; +}; + +#endif //TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYFIXTURE_H diff --git a/third-party/TeensyVariablePlayback/test/low_level/array/test_array_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/low_level/array/test_array_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..acd2c1b --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/array/test_array_mono_loop_forward_playback.cpp @@ -0,0 +1,43 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_ARRAY_READERTESTS_CPP +#define TEENSY_RESAMPLING_SDREADER_ARRAY_READERTESTS_CPP + +#include +#include "ResamplingArrayFixture.h" +extern unsigned char kick_raw[]; +extern unsigned int kick_raw_len; // in bytes, divide by 2 to get samples + +BOOST_AUTO_TEST_SUITE(test_array_mono_loop_forward_playback) + + BOOST_FIXTURE_TEST_CASE(ReadForwardLoopAtRegularPlaybackRate, ResamplingArrayFixture) { + + const uint32_t expectedDataSize = kick_raw_len; // 32 16bit samples = 64 bytes of space + printf("ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + + resamplingArrayReader->begin(); + resamplingArrayReader->setPlaybackRate(1.0f); + resamplingArrayReader->playRaw((int16_t*)kick_raw, kick_raw_len/2, 1); + resamplingArrayReader->setInterpolationType(ResampleInterpolationType::resampleinterpolation_linear); + int16_t actual[256]; + int16_t *buffers[1] = { actual }; + + int j = 0, bytesRead = 0, total_bytes_read = 0, currentExpected = 0; + bool assertionsPass = true; + do { + bytesRead = resamplingArrayReader->read((void**)buffers, 256 ); // 256 samples + total_bytes_read += bytesRead; + //printf("j:%d bytesRead: %d \n", j, bytesRead); + //printf("\n"); + j++; + } while (j < 3); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingArrayReader->close(); + BOOST_CHECK_EQUAL(true, true); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_SDREADER_READERTESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/low_level/array/test_array_stereo_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/low_level/array/test_array_stereo_loop_forward_playback.cpp new file mode 100644 index 0000000..cc88552 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/array/test_array_stereo_loop_forward_playback.cpp @@ -0,0 +1,54 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_ARRAY_READERTESTS_CPP +#define TEENSY_RESAMPLING_SDREADER_ARRAY_READERTESTS_CPP + +#include +#include "ResamplingArrayFixture.h" +#include "AudioStream.h" + +extern unsigned char stereo_souljah_raw[]; +extern unsigned int stereo_souljah_raw_len; +BOOST_AUTO_TEST_SUITE(test_array_stereo_loop_forward_playback) + + unsigned char stereo_raw[] = { + 0x00, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x11, 0x00, + 0x02, 0x00, 0x12, 0x00, + 0x03, 0x00, 0x13, 0x00, + 0x04, 0x00, 0x14, 0x00, + 0x05, 0x00, 0x15, 0x00 }; + + unsigned int stereo_raw_length = 24; + + BOOST_FIXTURE_TEST_CASE(ReadForwardLoopAtRegularPlaybackRate, ResamplingArrayFixture) { + + const uint32_t expectedDataSize = stereo_souljah_raw_len; // 32 16bit samples = 64 bytes of space + printf("ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + + resamplingArrayReader->begin(); + resamplingArrayReader->setPlaybackRate(0.5f); + resamplingArrayReader->playRaw((int16_t*)stereo_raw, stereo_raw_length/4, 1); + resamplingArrayReader->setInterpolationType(ResampleInterpolationType::resampleinterpolation_none); + int16_t actual_left[256]; + int16_t actual_right[256]; + int16_t *buffers[2] = { actual_left, actual_right }; + + int j = 0, bytesRead = 0, total_bytes_read = 0, currentExpected = 0; + bool assertionsPass = true; + do { + bytesRead = resamplingArrayReader->read((void**)buffers, 256 ); // 256 samples + total_bytes_read += bytesRead; + //printf("j:%d bytesRead: %d \n", j, bytesRead); + j++; + } while (j < 3); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingArrayReader->close(); + BOOST_CHECK_EQUAL(true, true); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_SDREADER_READERTESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/low_level/arraywav/ResamplingArrayWavFixture.h b/third-party/TeensyVariablePlayback/test/low_level/arraywav/ResamplingArrayWavFixture.h new file mode 100644 index 0000000..9db4e38 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/arraywav/ResamplingArrayWavFixture.h @@ -0,0 +1,23 @@ +// +// Created by Nicholas Newdigate on 17/06/2021. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYWAVFIXTURE_H +#define TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYWAVFIXTURE_H + +#include "ResamplingArrayReader.h" + +struct ResamplingArrayWavFixture { + + ResamplingArrayWavFixture() { + resamplingArrayReader = new ResamplingArrayReader(); + } + + ~ResamplingArrayWavFixture() { + delete resamplingArrayReader; + } + + ResamplingArrayReader * resamplingArrayReader; +}; + +#endif //TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYWAVFIXTURE_H diff --git a/third-party/TeensyVariablePlayback/test/low_level/arraywav/test_array_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/low_level/arraywav/test_array_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..7d16e68 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/arraywav/test_array_mono_loop_forward_playback.cpp @@ -0,0 +1,44 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_ARRAYWAV_MONO_READERTESTS_CPP +#define TEENSY_RESAMPLING_SDREADER_ARRAYWAV_MONO_READERTESTS_CPP + +#include +#include "ResamplingArrayWavFixture.h" + +extern unsigned char mono_souljah_wav[]; +extern unsigned int mono_souljah_wav_len; + +BOOST_AUTO_TEST_SUITE(test_array_mono) + + BOOST_FIXTURE_TEST_CASE(ReadForwardLoopAtRegularPlaybackRate, ResamplingArrayWavFixture) { + + const uint32_t expectedDataSize = mono_souljah_wav_len; // 32 16bit samples = 64 bytes of space + printf("ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + + resamplingArrayReader->begin(); + resamplingArrayReader->setPlaybackRate(0.5f); + resamplingArrayReader->playWav((int16_t*)mono_souljah_wav, mono_souljah_wav_len/2); + resamplingArrayReader->setInterpolationType(ResampleInterpolationType::resampleinterpolation_linear); + int16_t actual[256]; + int16_t *buffers[1] = { actual }; + + int j = 0, bytesRead = 0, total_bytes_read = 0, currentExpected = 0; + bool assertionsPass = true; + do { + bytesRead = resamplingArrayReader->read((void**)buffers, 256 ); // 256 samples + total_bytes_read += bytesRead; + //printf("j:%d bytesRead: %d \n", j, bytesRead); + //printf("\n"); + j++; + } while (bytesRead > 0); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingArrayReader->close(); + BOOST_CHECK_EQUAL(true, true); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_SDREADER_ARRAYWAV_MONO_READERTESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/low_level/arraywav/test_array_stereo_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/low_level/arraywav/test_array_stereo_loop_forward_playback.cpp new file mode 100644 index 0000000..7364f28 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/arraywav/test_array_stereo_loop_forward_playback.cpp @@ -0,0 +1,44 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_ARRAYWAV_STEREO_READERTESTS_CPP +#define TEENSY_RESAMPLING_SDREADER_ARRAYWAV_STEREO_READERTESTS_CPP + +#include +#include "ResamplingArrayWavFixture.h" + +extern unsigned char stereo_souljah_wav[]; +extern unsigned int stereo_souljah_wav_len; + +BOOST_AUTO_TEST_SUITE(test_array_stereo) + + BOOST_FIXTURE_TEST_CASE(ReadForwardLoopAtRegularPlaybackRate, ResamplingArrayWavFixture) { + + const uint32_t expectedDataSize = stereo_souljah_wav_len; // 32 16bit samples = 64 bytes of space + printf("ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + + resamplingArrayReader->begin(); + resamplingArrayReader->setPlaybackRate(1.0f); + resamplingArrayReader->playWav((int16_t*)stereo_souljah_wav, stereo_souljah_wav_len/2); + resamplingArrayReader->setInterpolationType(ResampleInterpolationType::resampleinterpolation_linear); + int16_t actualLeft[256], actualRight[256]; + int16_t *buffers[2] = { actualLeft, actualRight }; + + int j = 0, bytesRead = 0, total_bytes_read = 0, currentExpected = 0; + bool assertionsPass = true; + do { + bytesRead = resamplingArrayReader->read((void**)buffers, 256 ); // 256 samples + total_bytes_read += bytesRead; + //printf("j:%d bytesRead: %d \n", j, bytesRead); + //printf("\n"); + j++; + } while (bytesRead > 0); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingArrayReader->close(); + BOOST_CHECK_EQUAL(true, true); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_SDREADER_ARRAYWAV_STEREO_READERTESTS_CPP \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/test/low_level/indexedfile/IndexedFileFixture.h b/third-party/TeensyVariablePlayback/test/low_level/indexedfile/IndexedFileFixture.h new file mode 100644 index 0000000..967d844 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/indexedfile/IndexedFileFixture.h @@ -0,0 +1,16 @@ +#ifndef TEENSY_VARIABLE_PLAYBACK_TEST_LOWLEVEL_INDEXEDFILE_INDEXEDFILEFIXTURE_H +#define TEENSY_VARIABLE_PLAYBACK_TEST_LOWLEVEL_INDEXEDFILE_INDEXEDFILEFIXTURE_H + +#include "IndexableFile.h" + +struct IndexableFileFixture { + + IndexableFileFixture() { + } + + ~IndexableFileFixture() { + } + +}; + +#endif //TEENSY_VARIABLE_PLAYBACK_TEST_LOWLEVEL_INDEXEDFILE_INDEXEDFILEFIXTURE_H diff --git a/third-party/TeensyVariablePlayback/test/low_level/indexedfile/test_indexablefile.cpp b/third-party/TeensyVariablePlayback/test/low_level/indexedfile/test_indexablefile.cpp new file mode 100644 index 0000000..35c416c --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/indexedfile/test_indexablefile.cpp @@ -0,0 +1,32 @@ +#include +#include "IndexedFileFixture.h" + +#include +#include "IndexableFile.h" + +BOOST_AUTO_TEST_SUITE(test_indexablefile) + + BOOST_FIXTURE_TEST_CASE(basic_test, IndexableFileFixture) { + + const uint16_t sample_size = 30; + int16_t file_contents[sample_size] = {0}; + for (int i=0; i indexable("blah.h"); // use max 2 buffers, with 16 elements each.... + + /* + for (int i=0; i0; i--) { + std::cout << i-1 << " " << (int)indexable[i-1] << std::endl; + } + */ + indexable.close(); + } + +BOOST_AUTO_TEST_SUITE_END() diff --git a/third-party/TeensyVariablePlayback/test/low_level/sd/ResamplingReaderFixture.h b/third-party/TeensyVariablePlayback/test/low_level/sd/ResamplingReaderFixture.h new file mode 100644 index 0000000..42f4e92 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/sd/ResamplingReaderFixture.h @@ -0,0 +1,23 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_RESAMPLINGREADERFIXTURE_H +#define TEENSY_RESAMPLING_SDREADER_RESAMPLINGREADERFIXTURE_H + +#include "ResamplingSdReader.h" + +struct ResamplingReaderFixture { + + ResamplingReaderFixture() { + resamplingSdReader = new ResamplingSdReader(); + } + + ~ResamplingReaderFixture() { + delete resamplingSdReader; + } + + ResamplingSdReader * resamplingSdReader; +}; + +#endif //TEENSY_RESAMPLING_SDREADER_RESAMPLINGREADERFIXTURE_H diff --git a/third-party/TeensyVariablePlayback/test/low_level/sd/readme.MD b/third-party/TeensyVariablePlayback/test/low_level/sd/readme.MD new file mode 100644 index 0000000..fcaf731 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/sd/readme.MD @@ -0,0 +1,5 @@ +#Don't Run Unit Tests on the Arduino Device or Emulator +https://stackoverflow.com/a/11437456 + +includes code from the following repos: +https://github.com/IronSavior/dsm2_tx \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/test/low_level/sd/test_raw_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/low_level/sd/test_raw_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..f899930 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/sd/test_raw_mono_loop_forward_playback.cpp @@ -0,0 +1,97 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_READER_MONO_LOOP_TESTS_CPP +#define TEENSY_RESAMPLING_SDREADER_READER_MONO_LOOP_TESTS_CPP +#include +#include "ResamplingReaderFixture.h" + +BOOST_AUTO_TEST_SUITE(test_raw_mono_loop_forward_playback) + + BOOST_FIXTURE_TEST_CASE(ReadForwardLoopAtRegularPlaybackRate, ResamplingReaderFixture) { + + const uint32_t expectedDataSize = 32; // 32 16bit samples = 64 bytes of space + printf("ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + int16_t expected[expectedDataSize]; + for (int16_t i = 0; i < expectedDataSize; i++) { + expected[i] = i; + } + SD.setSDCardFileData((char*) expected, expectedDataSize * 2); + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(1.0); + resamplingSdReader->playRaw("test2.bin", 1); + resamplingSdReader->setLoopType(looptype_repeat); + int16_t actual[256]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0, currentExpected = 0; + bool assertionsPass = true; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); // 256 samples + total_bytes_read += samplesRead * 2; + printf("j:%d samplesRead: %d \n", j, samplesRead); + + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", currentExpected, actual[i]); + + if (currentExpected != actual[i]) { + assertionsPass = false; + BOOST_FAIL("Value not as expected!!!"); + } + + currentExpected++; + currentExpected %= expectedDataSize; + } + + printf("\n"); + j++; + } while (j < 100); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingSdReader->close(); + + } + + BOOST_FIXTURE_TEST_CASE(ReadForwardLoopAtHalfPlaybackRate, ResamplingReaderFixture) { + + const uint32_t size_of_datasource = 800; + printf("ReadForwardAtRegularPlaybackRate(%d)\n", size_of_datasource); + int16_t dataSource[size_of_datasource]; + for (int16_t i = 0; i < size_of_datasource; i++) { + dataSource[i] = i; + } + SD.setSDCardFileData((char*) dataSource, size_of_datasource * 2); + + const int16_t expectedSize = size_of_datasource * 2; + int16_t expected[expectedSize]; + for (int16_t i = 0; i < expectedSize; i++) { + expected[i] = i / 2; + } + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(0.5); + resamplingSdReader->playRaw("test2.bin", 1); + resamplingSdReader->setLoopType(looptype_none); + int16_t actual[expectedSize]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); + total_bytes_read += samplesRead * 2; + printf("j:%d samplesRead: %d: ", j, samplesRead); + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", expected[j * 256 + i], actual[i]); + } + printf("\n"); + + if (samplesRead != 0) + BOOST_CHECK_EQUAL_COLLECTIONS(&expected[j * 256], &expected[j * 256 + samplesRead - 1], &actual[0], &actual[samplesRead - 1]); + j++; + } while (samplesRead > 0); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingSdReader->close(); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_SDREADER_READER_MONO_LOOP_TESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/low_level/sd/test_raw_mono_noloop_forward_double_rate_playback.cpp b/third-party/TeensyVariablePlayback/test/low_level/sd/test_raw_mono_noloop_forward_double_rate_playback.cpp new file mode 100644 index 0000000..a2d32a6 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/sd/test_raw_mono_noloop_forward_double_rate_playback.cpp @@ -0,0 +1,115 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_READER_MONO_NOLOOP_TESTS_CPP +#define TEENSY_RESAMPLING_SDREADER_READER_MONO_NOLOOP_TESTS_CPP +#include +#include "ResamplingReaderFixture.h" +#include + +BOOST_AUTO_TEST_SUITE(test_raw_mono_noloop_forward_double_rate_playback) + const double playBackRate = 2.0; + + void populateDataSourceAndSetSDCardMockData(const uint32_t size_of_datasource, int16_t dataSource[]) { + for (int16_t i = 0; i < size_of_datasource; i++) { + dataSource[i] = i; + } + SD.setSDCardFileData((char *) dataSource, size_of_datasource * 2); + } + + void testReadForwardAtDoublePlaybackRate(const uint32_t size_of_datasource, ResamplingSdReader *resamplingSdReader) { + printf("test_raw_mono_noloop_forward_double_rate_playback::testReadForwardAtDoublePlaybackRate(rate:%.2f\tsamples:%d)\n", playBackRate, size_of_datasource); + + int16_t dataSource[size_of_datasource]; + populateDataSourceAndSetSDCardMockData(size_of_datasource, dataSource); + + const int16_t expectedSize = ceil(size_of_datasource / 2.0); + int16_t expected[expectedSize]; + for (int16_t i = 0; i < expectedSize; i++) { + expected[i] = i * 2; + } + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(playBackRate); + resamplingSdReader->playRaw("test2.bin", 1); + resamplingSdReader->setLoopType(looptype_none); + int16_t actual[256]; + int16_t *buffers[1] = { actual }; + + int j = 0, samplesRead = 0, total_bytes_read = 0; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256); + total_bytes_read += samplesRead * 2; + printf("j:%d samplesRead: %d: ", j, samplesRead); + for (int i = 0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", expected[j * 256 + i], actual[i]); + } + printf("\n"); + if (samplesRead != 0) + BOOST_CHECK_EQUAL_COLLECTIONS(&expected[j * 256], &expected[j * 256 + samplesRead - 1], &actual[0], &actual[samplesRead - 1]); + j++; + } while (samplesRead > 0); + printf("actual: bytes read: %d; samples read: %d \t\texpected: bytes read: %d; samples read:%d\n", + total_bytes_read, total_bytes_read / 2, expectedSize * 2, expectedSize); + resamplingSdReader->close(); + + BOOST_CHECK_EQUAL(expectedSize * 2, total_bytes_read ); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas0Samples, ResamplingReaderFixture) + { + testReadForwardAtDoublePlaybackRate(0, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas1Sample, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(1, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas2Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(2, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas4Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(2, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas255Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(255, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas256Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(256, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas257Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(257, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas500Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(500, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas512Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(512, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas800Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(800, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas1023Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(1023, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas1024Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(1024, resamplingSdReader); + } + + BOOST_FIXTURE_TEST_CASE(RawFileHas1025Samples, ResamplingReaderFixture) { + testReadForwardAtDoublePlaybackRate(1025, resamplingSdReader); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_SDREADER_READER_MONO_NOLOOP_TESTS_CPP \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/test/low_level/sd/test_raw_mono_noloop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/low_level/sd/test_raw_mono_noloop_forward_playback.cpp new file mode 100644 index 0000000..f22a678 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/sd/test_raw_mono_noloop_forward_playback.cpp @@ -0,0 +1,95 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_READER_MONO_FORWARD_TESTS_CPP +#define TEENSY_RESAMPLING_SDREADER_READER_MONO_FORWARD_TESTS_CPP +#define BOOST_AUTO_TEST_MAIN +#define BOOST_TEST_MODULE ResamplingReaderTests +#define BOOST_TEST_DYN_LINK +#include +#include "ResamplingReaderFixture.h" + +BOOST_AUTO_TEST_SUITE(test_raw_mono_noloop_forward_playback) + + BOOST_FIXTURE_TEST_CASE(ReadForwardAtRegularPlaybackRate, ResamplingReaderFixture) { + + const uint32_t expectedDataSize = 1600; + printf("ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + int16_t expected[expectedDataSize]; + for (int16_t i = 0; i < expectedDataSize; i++) { + expected[i] = i; + } + SD.setSDCardFileData((char*) expected, expectedDataSize * 2); + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(1.0); + resamplingSdReader->playRaw("test2.bin", 1); + resamplingSdReader->setLoopType(looptype_none); + resamplingSdReader->setInterpolationType(ResampleInterpolationType::resampleinterpolation_quadratic); + int16_t actual[1024]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); + total_bytes_read += samplesRead * 2; + printf("j:%d samplesRead: %d \n", j, samplesRead); + + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", expected[j * 256 + i], actual[j + i]); + } + printf("\n"); + j++; + } while (samplesRead > 0); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingSdReader->close(); + + //BOOST_CHECK_EQUAL_COLLECTIONS(&expected[0], &expected[expectedDataSize-1], &actual[0], &actual[(total_bytes_read / 2)-1]); + } + + BOOST_FIXTURE_TEST_CASE(ReadForwardAtHalfPlaybackRate, ResamplingReaderFixture) { + + const uint32_t size_of_datasource = 800; + printf("ReadForwardAtRegularPlaybackRate(%d)\n", size_of_datasource); + int16_t dataSource[size_of_datasource]; + for (int16_t i = 0; i < size_of_datasource; i++) { + dataSource[i] = i; + } + SD.setSDCardFileData((char*) dataSource, size_of_datasource * 2); + + const int16_t expectedSize = size_of_datasource * 2; + int16_t expected[expectedSize]; + for (int16_t i = 0; i < expectedSize; i++) { + expected[i] = i / 2; + } + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(0.5); + resamplingSdReader->playRaw("test2.bin", 1); + resamplingSdReader->setLoopType(looptype_none); + //resamplingSdReader->setInterpolationType(ResampleInterpolationType::resampleinterpolation_quadratic); + + int16_t actual[expectedSize]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); + total_bytes_read += samplesRead * 2; + printf("j:%d samplesRead: %d: ", j, samplesRead); + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", expected[j * 256 + i], actual[i]); + } + printf("\n"); + if (samplesRead != 0) + BOOST_CHECK_EQUAL_COLLECTIONS(&expected[j * 256], &expected[j * 256 + samplesRead - 1], &actual[0], &actual[samplesRead - 1]); + + j++; + } while (samplesRead > 0); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingSdReader->close(); + + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_SDREADER_READER_MONO_FORWARD_TESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/low_level/sd/test_wav_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/low_level/sd/test_wav_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..f708675 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/sd/test_wav_mono_loop_forward_playback.cpp @@ -0,0 +1,214 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_WAVSDREADER_READER_MONO_LOOP_FORWARD_TESTS_CPP +#define TEENSY_RESAMPLING_WAVSDREADER_READER_MONO_LOOP_FORWARD_TESTS_CPP +#include +#include "ResamplingReaderFixture.h" + +BOOST_AUTO_TEST_SUITE(test_wav_mono_loop_forward_playback) + uint16_t test_sndhdrdata_sndhdr_wav[] = { + 0x4952, 0x4646, 0x0038, 0x0000, 0x4157, 0x4556, + 0x6d66, 0x2074, 0x0010, 0x0000, 0x0001, 0x0001, + 0xac44, 0x0000, 0xb110, 0x0002, 0x0004, 0x0010, + 0x6164, 0x6174, 0x0014, 0x0000 + }; + unsigned int test_sndhdrdata_sndhdr_wav_len = 22; // 22 int16_t = 44 bytes = size of wave header + + BOOST_FIXTURE_TEST_CASE(ReadForwardLoopAtRegularPlaybackRate, ResamplingReaderFixture) { + + const uint32_t expectedDataSize = 32; // = 64 bytes + test_sndhdrdata_sndhdr_wav[20] = expectedDataSize * 2; + printf("test_wav_mono_loop_forward_playback::ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + int16_t mockFileBytes[expectedDataSize + test_sndhdrdata_sndhdr_wav_len]; + for (int16_t i = 0; i < test_sndhdrdata_sndhdr_wav_len; i++) { + mockFileBytes[i] = test_sndhdrdata_sndhdr_wav[i]; + } + for (int16_t i = 0; i < expectedDataSize; i++) { + mockFileBytes[i + test_sndhdrdata_sndhdr_wav_len] = i; + } + SD.setSDCardFileData((char*) mockFileBytes, (expectedDataSize + test_sndhdrdata_sndhdr_wav_len) * 2); + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(1.0); + resamplingSdReader->playWav("test2.bin"); + resamplingSdReader->setLoopType(looptype_repeat); + int16_t actual[256]; + int16_t *buffers[1] = { actual }; + int j = 0, bytesRead = 0, total_bytes_read = 0, currentExpected = 0; + bool assertionsPass = true; + do { + bytesRead = resamplingSdReader->read((void**)buffers, 256 ); // 256 samples + total_bytes_read += bytesRead; + //printf("j:%d bytesRead: %d \n", j, bytesRead); + + for (int i=0; i < bytesRead/2; i++) { + printf("\t\t[%x]:%x", currentExpected, actual[i]); + + if (currentExpected != actual[i]) { + assertionsPass = false; + BOOST_FAIL("Value not as expected!!!"); + } + + currentExpected++; + currentExpected %= expectedDataSize; + } + + printf("\n"); + j++; + } while (j < 100); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingSdReader->close(); + + BOOST_CHECK_EQUAL( true, assertionsPass); + + } + + BOOST_FIXTURE_TEST_CASE(ReadForwardLoopAtRegularPlaybackRateWithLoopFinish, ResamplingReaderFixture) { + + const uint32_t expectedDataSize = 32; // = 64 bytes + test_sndhdrdata_sndhdr_wav[20] = expectedDataSize * 2; + + printf("test_wav_mono_loop_forward_playback::ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + int16_t mockFileBytes[expectedDataSize + test_sndhdrdata_sndhdr_wav_len]; + for (int16_t i = 0; i < test_sndhdrdata_sndhdr_wav_len; i++) { + mockFileBytes[i] = test_sndhdrdata_sndhdr_wav[i]; + } + for (int16_t i = 0; i < expectedDataSize; i++) { + mockFileBytes[i + test_sndhdrdata_sndhdr_wav_len] = i; + } + SD.setSDCardFileData((char*) mockFileBytes, (expectedDataSize + test_sndhdrdata_sndhdr_wav_len) * 2); + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(1.0); + resamplingSdReader->playWav("test2.bin"); + resamplingSdReader->setLoopType(looptype_repeat); + resamplingSdReader->setLoopFinish(8); + + int16_t actual[256]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0, currentExpected = 0; + bool assertionsPass = true; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); // 256 samples + total_bytes_read += samplesRead * 2; + printf("j:%d samplesRead: %d \n", j, samplesRead); + + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", currentExpected, actual[i]); + + if (currentExpected != actual[i]) { + assertionsPass = false; + BOOST_FAIL("Value not as expected!!!"); + } + + currentExpected++; + currentExpected %= 8; + } + + printf("\n"); + j++; + } while (j < 100); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingSdReader->close(); + + BOOST_CHECK_EQUAL( true, assertionsPass); + + } + + BOOST_FIXTURE_TEST_CASE(ReadForwardLoopAtRegularPlaybackRateWithLoopStartAndFinish, ResamplingReaderFixture) { + + const uint32_t expectedDataSize = 32; // = 64 bytes + test_sndhdrdata_sndhdr_wav[20] = expectedDataSize * 2; + printf("test_wav_mono_loop_forward_playback::ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + int16_t mockFileBytes[expectedDataSize + test_sndhdrdata_sndhdr_wav_len]; + for (int16_t i = 0; i < test_sndhdrdata_sndhdr_wav_len; i++) { + mockFileBytes[i] = test_sndhdrdata_sndhdr_wav[i]; + } + for (int16_t i = 0; i < expectedDataSize; i++) { + mockFileBytes[i + test_sndhdrdata_sndhdr_wav_len] = i; + } + SD.setSDCardFileData((char*) mockFileBytes, (expectedDataSize + test_sndhdrdata_sndhdr_wav_len) * 2); + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(1.0); + resamplingSdReader->playWav("test2.bin"); + resamplingSdReader->setLoopType(looptype_repeat); + resamplingSdReader->setLoopFinish(8); + + int16_t actual[256]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0, currentExpected = 0; + bool assertionsPass = true; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); // 256 samples + total_bytes_read += samplesRead * 2; + printf("j:%d bytesRead: %d \n", j, total_bytes_read); + + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", currentExpected, actual[i]); + + if (currentExpected != actual[i]) { + assertionsPass = false; + BOOST_FAIL("Value not as expected!!!"); + } + + currentExpected++; + currentExpected %= 8; + } + + printf("\n"); + j++; + } while (j < 100); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingSdReader->close(); + + BOOST_CHECK_EQUAL( true, assertionsPass); + + } + + BOOST_FIXTURE_TEST_CASE(ReadForwardLoopAtHalfPlaybackRate, ResamplingReaderFixture) { + + const uint32_t size_of_datasource = 800; + test_sndhdrdata_sndhdr_wav[20] = size_of_datasource * 2; + printf("ReadForwardAtRegularPlaybackRate(%d)\n", size_of_datasource); + int16_t dataSource[size_of_datasource]; + for (int16_t i = 0; i < size_of_datasource; i++) { + dataSource[i] = i; + } + SD.setSDCardFileData((char*) dataSource, size_of_datasource * 2); + + const int16_t expectedSize = size_of_datasource * 2; + int16_t expected[expectedSize]; + for (int16_t i = 0; i < expectedSize; i++) { + expected[i] = i / 2; + } + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(0.5); + resamplingSdReader->playWav("test2.bin"); + resamplingSdReader->setLoopType(looptype_none); + int16_t actual[expectedSize]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); + total_bytes_read += samplesRead * 2; + printf("j:%d samplesRead: %d: ", j, samplesRead); + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", expected[j * 256 + i], actual[j + i]); + } + printf("\n"); + + if (samplesRead != 0) + BOOST_CHECK_EQUAL_COLLECTIONS(&expected[j * 256], &expected[j * 256 + samplesRead - 1], &actual[0], &actual[samplesRead - 1]); + j++; + } while (samplesRead > 0); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingSdReader->close(); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_WAVSDREADER_READER_MONO_LOOP_FORWARD_TESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/low_level/sd/test_wav_mono_noloop_backward_playback.cpp b/third-party/TeensyVariablePlayback/test/low_level/sd/test_wav_mono_noloop_backward_playback.cpp new file mode 100644 index 0000000..d185763 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/sd/test_wav_mono_noloop_backward_playback.cpp @@ -0,0 +1,107 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_WAVSDREADER_READER_MONO_NOLOOP_BACKWARD_TESTS_CPP +#define TEENSY_RESAMPLING_WAVSDREADER_READER_MONO_NOLOOP_BACKWARD_TESTS_CPP +#include +#include "ResamplingReaderFixture.h" + +BOOST_AUTO_TEST_SUITE(test_wav_mono_noloop_backward_playback) + + uint16_t test_sndhdrdata_sndhdr_wav[] = { + 0x4952, 0x4646, 0x0038, 0x0000, 0x4157, 0x4556, + 0x6d66, 0x2074, 0x0010, 0x0000, 0x0001, 0x0001, + 0xac44, 0x0000, 0xb110, 0x0002, 0x0004, 0x0010, + 0x6164, 0x6174, 0x0014, 0x0000 + }; + unsigned int test_sndhdrdata_sndhdr_wav_len = 22; // 22 int16_t = 44 bytes = size of wave header + + BOOST_FIXTURE_TEST_CASE(ReadBackwardAtRegularPlaybackRate, ResamplingReaderFixture) { + + const uint32_t expectedDataSize = 258; + + test_sndhdrdata_sndhdr_wav[20] = expectedDataSize * 2; + printf("test_wav_mono_noloop_forward_playback::ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + int16_t mockFileBytes[expectedDataSize + test_sndhdrdata_sndhdr_wav_len]; + int16_t expected[expectedDataSize]; + for (int16_t i = 0; i < test_sndhdrdata_sndhdr_wav_len; i++) { + mockFileBytes[i] = test_sndhdrdata_sndhdr_wav[i]; + } + for (int16_t i = 0; i < expectedDataSize; i++) { + mockFileBytes[i + test_sndhdrdata_sndhdr_wav_len] = i; + expected[i] = expectedDataSize - i - 1; + } + SD.setSDCardFileData((char*) mockFileBytes, (expectedDataSize + test_sndhdrdata_sndhdr_wav_len) * 2); + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(-1.0); + resamplingSdReader->playWav("test2.bin"); + resamplingSdReader->setLoopType(looptype_none); + int16_t actual[1024]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); + total_bytes_read += samplesRead * 2; + printf("j:%d bytessamplesReadRead: %d \n", j, samplesRead); + + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", expected[j * 256 + i], actual[i]); + } + printf("\n"); + if (samplesRead != 0) + BOOST_CHECK_EQUAL_COLLECTIONS(&expected[j * 256], &expected[j * 256 + samplesRead - 1], &actual[0], &actual[samplesRead - 1]); + + j++; + } while (samplesRead > 0); + printf("total_bytes_read: %d \n", total_bytes_read); + BOOST_CHECK_EQUAL(resamplingSdReader->isPlaying(), false); + resamplingSdReader->close(); + } + + BOOST_FIXTURE_TEST_CASE(ReadBackwardAtHalfPlaybackRate, ResamplingReaderFixture) { + + const uint32_t expectedDataSize = 258; + test_sndhdrdata_sndhdr_wav[20] = expectedDataSize * 2; + printf("test_wav_mono_noloop_forward_playback::ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + int16_t mockFileBytes[expectedDataSize + test_sndhdrdata_sndhdr_wav_len]; + int16_t expected[expectedDataSize * 2]; + for (int16_t i = 0; i < test_sndhdrdata_sndhdr_wav_len; i++) { + mockFileBytes[i] = test_sndhdrdata_sndhdr_wav[i]; + } + for (int16_t i = 0; i < expectedDataSize; i++) { + mockFileBytes[i + test_sndhdrdata_sndhdr_wav_len] = i; + } + for (int16_t i = 0; i < expectedDataSize * 2; i++) { + expected[i] = expectedDataSize - (i/2) - 1; + } + + SD.setSDCardFileData((char*) mockFileBytes, (expectedDataSize + test_sndhdrdata_sndhdr_wav_len) * 2); + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(-0.5); + resamplingSdReader->playWav("test2.bin"); + resamplingSdReader->setLoopType(looptype_none); + int16_t actual[expectedDataSize*2]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); + total_bytes_read += samplesRead; + printf("j:%d samplesRead: %d: ", j, samplesRead); + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", expected[j * 256 + i], actual[j + i]); + } + printf("\n"); + if (samplesRead != 0) + BOOST_CHECK_EQUAL_COLLECTIONS(&expected[j * 256], &expected[j * 256 + samplesRead - 1], &actual[0], &actual[samplesRead - 1]); + j++; + } while (samplesRead > 0); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingSdReader->close(); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_WAVSDREADER_READER_MONO_NOLOOP_BACKWARD_TESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/low_level/sd/test_wav_mono_noloop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/low_level/sd/test_wav_mono_noloop_forward_playback.cpp new file mode 100644 index 0000000..09f249d --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/sd/test_wav_mono_noloop_forward_playback.cpp @@ -0,0 +1,103 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_WAVSDREADER_READER_MONO_NOLOOP_FORWARD_TESTS_CPP +#define TEENSY_RESAMPLING_WAVSDREADER_READER_MONO_NOLOOP_FORWARD_TESTS_CPP +#include +#include "ResamplingReaderFixture.h" + +BOOST_AUTO_TEST_SUITE(test_wav_mono_noloop_forward_playback) + + uint16_t test_sndhdrdata_sndhdr_wav[] = { + 0x4952, 0x4646, 0x0038, 0x0000, 0x4157, 0x4556, + 0x6d66, 0x2074, 0x0010, 0x0000, 0x0001, 0x0001, + 0xac44, 0x0000, 0xb110, 0x0002, 0x0004, 0x0010, + 0x6164, 0x6174, 0x0014, 0x0000 + }; + unsigned int test_sndhdrdata_sndhdr_wav_len = 22; // 22 int16_t = 44 bytes = size of wave header + + BOOST_FIXTURE_TEST_CASE(ReadForwardAtRegularPlaybackRate, ResamplingReaderFixture) { + + const uint32_t expectedDataSize = 257; + test_sndhdrdata_sndhdr_wav[20] = expectedDataSize * 2; + printf("test_wav_mono_noloop_forward_playback::ReadForwardAtRegularPlaybackRate(%d)\n", expectedDataSize); + int16_t mockFileBytes[expectedDataSize + test_sndhdrdata_sndhdr_wav_len]; + int16_t expected[expectedDataSize]; + for (int16_t i = 0; i < test_sndhdrdata_sndhdr_wav_len; i++) { + mockFileBytes[i] = test_sndhdrdata_sndhdr_wav[i]; + } + for (int16_t i = 0; i < expectedDataSize; i++) { + mockFileBytes[i + test_sndhdrdata_sndhdr_wav_len] = i; + expected[i] = i; + } + SD.setSDCardFileData((char*) mockFileBytes, (expectedDataSize + test_sndhdrdata_sndhdr_wav_len) * 2); + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(1.0); + resamplingSdReader->playWav("test2.bin"); + resamplingSdReader->setLoopType(looptype_none); + int16_t actual[1024]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); + total_bytes_read += samplesRead * 2; + //printf("j:%d bytesRead: %d \n", j, samplesRead); + + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", expected[j * 256 + i], actual[j + i]); + } + printf("\n"); + if (samplesRead != 0) + BOOST_CHECK_EQUAL_COLLECTIONS(&expected[j * 256], &expected[j * 256 + samplesRead - 1], &actual[0], &actual[samplesRead - 1]); + j++; + } while (samplesRead > 0); + printf("total_bytes_read: %d \n", total_bytes_read); + BOOST_CHECK_EQUAL(resamplingSdReader->isPlaying(), false); + resamplingSdReader->close(); + } + + BOOST_FIXTURE_TEST_CASE(ReadForwardAtHalfPlaybackRate, ResamplingReaderFixture) { + + const uint32_t size_of_datasource = 800; + test_sndhdrdata_sndhdr_wav[20] = size_of_datasource * 2; + printf("ReadForwardAtRegularPlaybackRate(%d)\n", size_of_datasource); + int16_t dataSource[size_of_datasource]; + for (int16_t i = 0; i < size_of_datasource; i++) { + dataSource[i] = i; + } + SD.setSDCardFileData((char*) dataSource, size_of_datasource * 2); + + const int16_t expectedSize = size_of_datasource * 2; + int16_t expected[expectedSize]; + for (int16_t i = 0; i < expectedSize; i++) { + expected[i] = i / 2; + } + + resamplingSdReader->begin(); + resamplingSdReader->setPlaybackRate(0.5); + resamplingSdReader->playWav("test2.bin"); + resamplingSdReader->setLoopType(looptype_none); + int16_t actual[expectedSize]; + int16_t *buffers[1] = { actual }; + int j = 0, samplesRead = 0, total_bytes_read = 0; + do { + samplesRead = resamplingSdReader->read((void**)buffers, 256 ); + total_bytes_read += samplesRead * 2; + printf("j:%d samplesRead: %d: ", j, samplesRead); + for (int i=0; i < samplesRead; i++) { + printf("\t\t[%x]:%x", expected[j * 256 + i], actual[j + i]); + } + printf("\n"); + if (samplesRead != 0) + BOOST_CHECK_EQUAL_COLLECTIONS(&expected[j * 256], &expected[j * 256 + samplesRead - 1], &actual[0], &actual[samplesRead - 1]); + j++; + } while (samplesRead > 0); + printf("total_bytes_read: %d \n", total_bytes_read); + resamplingSdReader->close(); + } + +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_WAVSDREADER_READER_MONO_NOLOOP_FORWARD_TESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/low_level/wav_header/WaveHeaderParserFixture.h b/third-party/TeensyVariablePlayback/test/low_level/wav_header/WaveHeaderParserFixture.h new file mode 100644 index 0000000..aacd82e --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/wav_header/WaveHeaderParserFixture.h @@ -0,0 +1,23 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_RESAMPLINGREADERFIXTURE_H +#define TEENSY_RESAMPLING_SDREADER_RESAMPLINGREADERFIXTURE_H + +#include "waveheaderparser.h" + +struct WaveHeaderParserFixture { + + WaveHeaderParserFixture() { + waveHeaderParser = new WaveHeaderParser(); + } + + ~WaveHeaderParserFixture() { + delete waveHeaderParser; + } + + WaveHeaderParser * waveHeaderParser; +}; + +#endif //TEENSY_RESAMPLING_SDREADER_RESAMPLINGREADERFIXTURE_H diff --git a/third-party/TeensyVariablePlayback/test/low_level/wav_header/test_parse_wave_header.cpp b/third-party/TeensyVariablePlayback/test/low_level/wav_header/test_parse_wave_header.cpp new file mode 100644 index 0000000..59096e2 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/low_level/wav_header/test_parse_wave_header.cpp @@ -0,0 +1,43 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_WAVEHEADER_PARSER_TESTS_CPP +#define TEENSY_RESAMPLING_WAVEHEADER_PARSER_TESTS_CPP + +#include +#include "WaveHeaderParserFixture.h" + +BOOST_AUTO_TEST_SUITE(WaveHeaderParsingTests) + + BOOST_FIXTURE_TEST_CASE(ReadWaveHeader, WaveHeaderParserFixture) { + + unsigned char test_sndhdrdata_sndhdr_wav[] = { + 0x52, 0x49, 0x46, 0x46, 0x38, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, + 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, + 0x64, 0x61, 0x74, 0x61, 0x14, 0x00, 0x00, 0x00 + }; + unsigned int test_sndhdrdata_sndhdr_wav_len = 44; + + SD.setSDCardFileData((char*) test_sndhdrdata_sndhdr_wav, test_sndhdrdata_sndhdr_wav_len); + + wav_header header; + wav_data_header data_header; + bool success = waveHeaderParser->readWaveHeader("blah.wav", header, data_header); + BOOST_CHECK_EQUAL(success, true); + const char expectedRIFF[5] = "RIFF"; + BOOST_CHECK_EQUAL_COLLECTIONS(&header.riff_header[0], &header.riff_header[3],&expectedRIFF[0], &expectedRIFF[3]); + BOOST_CHECK_EQUAL(header.header_chunk_size,56); + const char expectedWave[5] = "WAVE"; + BOOST_CHECK_EQUAL_COLLECTIONS(&header.wave_header[0], &header.wave_header[3],&expectedWave[0], &expectedWave[3]); + const char expectedfmt[5] = "fmt "; + BOOST_CHECK_EQUAL_COLLECTIONS(&header.fmt_header[0], &header.fmt_header[3],&expectedfmt[0], &expectedfmt[3]); + const char expecteddata[5] = "data"; + BOOST_CHECK_EQUAL_COLLECTIONS(&data_header.data_header[0], &data_header.data_header[3],&expecteddata[0], &expecteddata[3]); + //BOOST_CHECK_EQUAL(File::numOpenFiles,0); + //BOOST_CHECK_EQUAL(File::numInstances,0); + } +BOOST_AUTO_TEST_SUITE_END() + +#endif //TEENSY_RESAMPLING_WAVEHEADER_PARSER_TESTS_CPP diff --git a/third-party/TeensyVariablePlayback/test/resources/input/PNO1C1.raw b/third-party/TeensyVariablePlayback/test/resources/input/PNO1C1.raw new file mode 100644 index 0000000..099e256 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/input/PNO1C1.raw differ diff --git a/third-party/TeensyVariablePlayback/test/resources/input/SDTEST1.wav b/third-party/TeensyVariablePlayback/test/resources/input/SDTEST1.wav new file mode 100644 index 0000000..2b0d694 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/input/SDTEST1.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/input/SDTEST2.wav b/third-party/TeensyVariablePlayback/test/resources/input/SDTEST2.wav new file mode 100644 index 0000000..ff06d67 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/input/SDTEST2.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/input/kick.raw b/third-party/TeensyVariablePlayback/test/resources/input/kick.raw new file mode 100644 index 0000000..67a7a7f Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/input/kick.raw differ diff --git a/third-party/TeensyVariablePlayback/test/resources/input/kick.wav b/third-party/TeensyVariablePlayback/test/resources/input/kick.wav new file mode 100644 index 0000000..6e477c2 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/input/kick.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/input/mono_souljah.wav b/third-party/TeensyVariablePlayback/test/resources/input/mono_souljah.wav new file mode 100644 index 0000000..206d8ed Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/input/mono_souljah.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/input/stereo_souljah.raw b/third-party/TeensyVariablePlayback/test/resources/input/stereo_souljah.raw new file mode 100644 index 0000000..c739709 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/input/stereo_souljah.raw differ diff --git a/third-party/TeensyVariablePlayback/test/resources/input/stereo_souljah.wav b/third-party/TeensyVariablePlayback/test/resources/input/stereo_souljah.wav new file mode 100644 index 0000000..c21f987 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/input/stereo_souljah.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_5000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_5000_quadratic_mono_noloop.wav new file mode 100644 index 0000000..676478c Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_5000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_5000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_5000_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..c2fbea5 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_5000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_7437_quadratic_mono_noloop.wav new file mode 100644 index 0000000..3c1d0d8 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_7437_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..336ce7f Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_0_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_0000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_0000_quadratic_mono_noloop.wav new file mode 100644 index 0000000..04b6b34 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_0000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_0000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_0000_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..20965f5 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_0000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_7437_quadratic_mono_noloop.wav new file mode 100644 index 0000000..a526adb Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_7437_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..554b89d Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_1_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_2_0000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_2_0000_quadratic_mono_noloop.wav new file mode 100644 index 0000000..bc3e5d4 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_2_0000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_2_0000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_2_0000_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..b83f94e Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_2_0000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_8_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_8_7437_quadratic_mono_noloop.wav new file mode 100644 index 0000000..7e4a8f2 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_8_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_8_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_8_7437_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..041ade6 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Array_fwd_8_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/SDTEST1.wav b/third-party/TeensyVariablePlayback/test/resources/reference/SDTEST1.wav new file mode 100644 index 0000000..60793b6 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/SDTEST1.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/SDTEST2.wav b/third-party/TeensyVariablePlayback/test/resources/reference/SDTEST2.wav new file mode 100644 index 0000000..1fa5819 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/SDTEST2.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_5000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_5000_quadratic_mono_noloop.wav new file mode 100644 index 0000000..48760ba Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_5000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_5000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_5000_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..7cdbe92 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_5000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_7437_quadratic_mono_noloop.wav new file mode 100644 index 0000000..bca72c4 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_7437_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..78f4797 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_0_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_0000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_0000_quadratic_mono_noloop.wav new file mode 100644 index 0000000..a7fea51 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_0000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_0000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_0000_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..59da2c7 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_0000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_7437_quadratic_mono_noloop.wav new file mode 100644 index 0000000..bbaa949 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_7437_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..2d6bb49 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_1_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_2_0000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_2_0000_quadratic_mono_noloop.wav new file mode 100644 index 0000000..2d5e61c Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_2_0000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_2_0000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_2_0000_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..7bef9fa Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_2_0000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_8_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_8_7437_quadratic_mono_noloop.wav new file mode 100644 index 0000000..149d709 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_8_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_8_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_8_7437_quadratic_stereo_noloop.wav new file mode 100644 index 0000000..5a1b65f Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/Wav_fwd_8_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/kick.wav b/third-party/TeensyVariablePlayback/test/resources/reference/kick.wav new file mode 100644 index 0000000..6e477c2 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/kick.wav differ diff --git a/third-party/TeensyVariablePlayback/test/resources/reference/stereo_souljah.wav b/third-party/TeensyVariablePlayback/test/resources/reference/stereo_souljah.wav new file mode 100644 index 0000000..c21f987 Binary files /dev/null and b/third-party/TeensyVariablePlayback/test/resources/reference/stereo_souljah.wav differ