diff --git a/config.h b/config.h index 1be95aa..8f4de26 100644 --- a/config.h +++ b/config.h @@ -60,7 +60,7 @@ // // Information about memory layout, etc.: https://www.pjrc.com/store/teensy41.html -#define VERSION "1.2.7" +#define VERSION "1.2.8" //************************************************************************************************* //* DEVICE SETTINGS @@ -73,6 +73,11 @@ #define MIDI_DEVICE_USB 1 #define MIDI_DEVICE_USB_HOST 1 +#ifdef MIDI_DEVICE_USB_HOST +#define USB_HOST_SERIAL_BAUD 38400 +#define USB_HOST_SERIAL_FORMAT USBHOST_SERIAL_8N1 +#endif + //************************************************************************************************* //* AUDIO HARDWARE SETTINGS //************************************************************************************************* @@ -525,7 +530,7 @@ #define ENGINE_MIN 0 #define ENGINE_MAX 2 -#define ENGINE_DEFAULT 1 // 0=Modern, 1=MkI, 2=OPL +#define ENGINE_DEFAULT 1 // 0=Modern, 1=MkI, 2=OPL #define PERFORMANCE_NUM_MIN 0 #define PERFORMANCE_NUM_MAX 99 diff --git a/midi_devices.hpp b/midi_devices.hpp index 4a177ff..0333944 100644 --- a/midi_devices.hpp +++ b/midi_devices.hpp @@ -43,6 +43,8 @@ MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, MIDI_DEVICE_DIN, midi_serial, MicroD #ifdef MIDI_DEVICE_USB_HOST USBHost usb_host; MIDIDevice midi_usb(usb_host); +USBSerial userial(usb_host); +MIDI_CREATE_CUSTOM_INSTANCE(USBSerial, userial, usbhost_midi_serial, MicroDexedSettings); #endif void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity); @@ -603,8 +605,8 @@ void handlePitchBend_MIDI_DEVICE_USB_HOST(byte inChannel, int inPitch) { handle_generic(inChannel, inPitch, '\0', MIDI_BY_USB_HOST, midi::PitchBend); } -void handleProgramChange_MIDI_DEVICE_USB_HOST(byte inChannel, byte inPitch) { - handle_generic(inChannel, inPitch, '\0', MIDI_BY_USB_HOST, midi::ProgramChange); +void handleProgramChange_MIDI_DEVICE_USB_HOST(byte inChannel, byte inProgram) { + handle_generic(inChannel, inProgram, '\0', MIDI_BY_USB_HOST, midi::ProgramChange); } void handleAfterTouchPoly_MIDI_DEVICE_USB_HOST(byte inChannel, byte inNoteNumber, byte inVelocity) { @@ -681,6 +683,110 @@ void handleSystemReset_MIDI_DEVICE_USB_HOST(void) { { handleRealTimeSystem_generic(inRealTime, MIDI_USB_HOST); } */ + + + + + + +void handleNoteOn_MIDI_DEVICE_USB_HOST_SERIAL(byte inChannel, byte inNoteNumber, byte inVelocity) { + handle_generic(inChannel, inNoteNumber, inVelocity, MIDI_BY_USB_HOST, midi::NoteOn); +} + +void handleNoteOff_MIDI_DEVICE_USB_HOST_SERIAL(byte inChannel, byte inNoteNumber, byte inVelocity) { + handle_generic(inChannel, inNoteNumber, inVelocity, MIDI_BY_USB_HOST, midi::NoteOff); +} + +void handleControlChange_MIDI_DEVICE_USB_HOST_SERIAL(byte inChannel, byte inData1, byte inData2) { + handle_generic(inChannel, inData1, inData2, MIDI_BY_USB_HOST, midi::ControlChange); +} + +void handleAfterTouch_MIDI_DEVICE_USB_HOST_SERIAL(byte inChannel, byte inPressure) { + handle_generic(inChannel, inPressure, '\0', MIDI_BY_USB_HOST, midi::AfterTouchChannel); +} + +void handlePitchBend_MIDI_DEVICE_USB_HOST_SERIAL(byte inChannel, int inPitch) { + handle_generic(inChannel, inPitch, '\0', MIDI_BY_USB_HOST, midi::PitchBend); +} + +void handleProgramChange_MIDI_DEVICE_USB_HOST_SERIAL(byte inChannel, byte inProgram) { + handle_generic(inChannel, inProgram, '\0', MIDI_BY_USB_HOST, midi::ProgramChange); +} + +void handleAfterTouchPoly_MIDI_DEVICE_USB_HOST_SERIAL(byte inChannel, byte inNoteNumber, byte inVelocity) { + handle_generic(inChannel, inNoteNumber, inVelocity, MIDI_BY_USB_HOST, midi::AfterTouchPoly); +} + +void handleSystemExclusive_MIDI_DEVICE_USB_HOST_SERIAL(byte *data, uint len) { + handleSystemExclusive_generic(data, len, MIDI_BY_USB_HOST); +} + +/* void handleSystemExclusiveChunk_MIDI_DEVICE_USB_HOST_SERIAL(byte *data, uint len, bool last) + { + handleSystemExclusiveChunk(data, len, last); + #ifdef DEBUG + Serial.print(F("[MIDI_USB_HOST] SysExChunk")); + #endif + if (configuration.sys.soft_midi_thru == 1) + { + #ifdef MIDI_DEVICE_DIN + midi_serial.sendSysEx(len, data, last); + #ifdef DEBUG + Serial.print(F(" THRU->MIDI_DIN")); + #endif + #endif + #ifdef MIDI_DEVICE_USB + usbMIDI.sendSysEx(len, data, last); + #ifdef DEBUG + Serial.print(F(" THRU->MIDI_USB")); + #endif + #endif + } + #ifdef DEBUG + Serial.println(); + #endif + } */ + +void handleTimeCodeQuarterFrame_MIDI_DEVICE_USB_HOST_SERIAL(midi::DataByte data) { + handleSystemCommon_generic(data, MIDI_BY_USB_HOST, midi::TimeCodeQuarterFrame); +} + +void handleSongSelect_MIDI_DEVICE_USB_HOST_SERIAL(byte inSong) { + handleSystemCommon_generic(inSong, MIDI_BY_USB_HOST, midi::SongSelect); +} + +void handleTuneRequest_MIDI_DEVICE_USB_HOST_SERIAL(void) { + handleSystemCommon_generic('\0', MIDI_BY_USB_HOST, midi::TuneRequest); +} + +void handleClock_MIDI_DEVICE_USB_HOST_SERIAL(void) { + handleRealtime_generic(MIDI_BY_USB_HOST, midi::Clock); +} + +void handleStart_MIDI_DEVICE_USB_HOST_SERIAL(void) { + handleRealtime_generic(MIDI_BY_USB_HOST, midi::Start); +} + +void handleContinue_MIDI_DEVICE_USB_HOST_SERIAL(void) { + handleRealtime_generic(MIDI_BY_USB_HOST, midi::Continue); +} + +void handleStop_MIDI_DEVICE_USB_HOST_SERIAL(void) { + handleRealtime_generic(MIDI_BY_USB_HOST, midi::Stop); +} + +void handleActiveSensing_MIDI_DEVICE_USB_HOST_SERIAL(void) { + handleRealtime_generic(MIDI_BY_USB_HOST, midi::ActiveSensing); +} + +void handleSystemReset_MIDI_DEVICE_USB_HOST_SERIAL(void) { + handleRealtime_generic(MIDI_BY_USB_HOST, midi::SystemReset); +} + +/* void handlRealTimeSystem_MIDI_DEVICE_USB_HOST_SERIAL(midi::MidiType inRealTime) + { + handleRealTimeSystem_generic(inRealTime, MIDI_USB_HOST); + } */ #endif // MIDI_DEVICE_USB_HOST /***************************************** @@ -872,6 +978,28 @@ FLASHMEM void setup_midi_devices(void) { midi_usb.setHandleActiveSensing(handleActiveSensing_MIDI_DEVICE_USB_HOST); midi_usb.setHandleSystemReset(handleSystemReset_MIDI_DEVICE_USB_HOST); //midi_usb.setHandleRealTimeSystem(handleRealTimeSystem_MIDI_DEVICE_USB_HOST); + + userial.begin(USB_HOST_SERIAL_BAUD,USB_HOST_SERIAL_FORMAT); + usbhost_midi_serial.setHandleNoteOn(handleNoteOn_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleNoteOff(handleNoteOff_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleControlChange(handleControlChange_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleAfterTouchChannel(handleAfterTouch_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandlePitchBend(handlePitchBend_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleProgramChange(handleProgramChange_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleSystemExclusive(handleSystemExclusive_MIDI_DEVICE_USB_HOST_SERIAL); + //usbhost_midi_serial.setHandleSystemExclusiveChunk(handleSystemExclusiveChunk_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleTimeCodeQuarterFrame(handleTimeCodeQuarterFrame_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleAfterTouchPoly(handleAfterTouchPoly_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleSongSelect(handleSongSelect_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleTuneRequest(handleTuneRequest_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleClock(handleClock_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleStart(handleStart_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleContinue(handleContinue_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleStop(handleStop_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleActiveSensing(handleActiveSensing_MIDI_DEVICE_USB_HOST_SERIAL); + usbhost_midi_serial.setHandleSystemReset(handleSystemReset_MIDI_DEVICE_USB_HOST_SERIAL); + //usbhost_midi_serial.setHandleRealTimeSystem(handleRealTimeSystem_MIDI_DEVICE_USB_HOST_SERIAL); + #ifdef DEBUG Serial.println(F("MIDI_DEVICE_USB_HOST enabled.")); #endif @@ -915,6 +1043,7 @@ FLASHMEM void check_midi_devices(void) { #ifdef MIDI_DEVICE_USB_HOST usb_host.Task(); midi_usb.read(); + usbhost_midi_serial.read(); #endif } diff --git a/third-party/TeensyVariablePlayback.O/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/CMakeLists.txt new file mode 100644 index 0000000..575c3f6 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/CMakeLists.txt @@ -0,0 +1,31 @@ +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) + import_arduino_library(LittleFS ${DEPSPATH}/LittleFS/src littlefs) + add_subdirectory(src) + add_subdirectory(examples) +else() + add_subdirectory(src) + add_subdirectory(test) + #add_subdirectory(extras/soundio/playqueue) + 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.O/LICENSE b/third-party/TeensyVariablePlayback.O/LICENSE new file mode 100644 index 0000000..93ec7f5 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/README.md b/third-party/TeensyVariablePlayback.O/README.md new file mode 100644 index 0000000..5885996 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/README.md @@ -0,0 +1,291 @@ +# 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 +* 26/02/2022: v1.0.16: + * add option for starting sample at begining or at loop start + ``` c + typedef enum play_start { + play_start_sample, + play_start_loop, + }; + + wave.setPlayStart(play_start::play_start_loop); + ``` +* 26/02/2022: v1.0.15: + * added support for dual playback head for seemless looping + * enable dual playback using linear crossfading + * set crossfade duration in number of samples + ``` c + AudioPlaySdResmp wave; + wave.setUseDualPlaybackHead(true); + wave.setCrossfadeDurationInSamples(1000); + wave.playRaw((int16_t*)kick_raw, kick_raw_len / 2, numberOfChannels); + wave.setLoopStart(0); + wave.setLoopFinish(3000); + ``` +* 16/06/2022: v1.0.14: + * refactored code to generic classes + * improve memory leaks + * remove calls to StartUsingSPI(), StopUsingSPI(), __disable_irq(), __enable_irq() + * intergated with SerialFlash and LittleFS +* 25/09/2021: v1.0.13: positionMillis() implemented for AudioPlaySdResmp +* 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 + You can run and test this code on your linux computer. You can write a teensy sketch, and with a few modifications, you can redirect the audio input and output to and from your soundcard. [Soundio](https://github.com/newdigate/teensy-audio-x86-stubs/tree/main/extras/soundio) bindings are optional, you can also run sketches and tests with no audio input or output. + You will need to install the following libraries. + +```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``` + + * 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.O/build-linux.sh b/third-party/TeensyVariablePlayback.O/build-linux.sh new file mode 100755 index 0000000..7e47c58 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/build-t41.sh b/third-party/TeensyVariablePlayback.O/build-t41.sh new file mode 100755 index 0000000..4670068 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/cmake/install_arduino_library.cmake b/third-party/TeensyVariablePlayback.O/cmake/install_arduino_library.cmake new file mode 100644 index 0000000..eee38a5 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/cmake/teensy_variable_playback.cmake.in b/third-party/TeensyVariablePlayback.O/cmake/teensy_variable_playback.cmake.in new file mode 100644 index 0000000..52c03a3 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/cmake/toolchains/teensy41.cmake b/third-party/TeensyVariablePlayback.O/cmake/toolchains/teensy41.cmake new file mode 100644 index 0000000..12ba556 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/cmake/uninstall.cmake b/third-party/TeensyVariablePlayback.O/cmake/uninstall.cmake new file mode 100644 index 0000000..a303d93 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/docs/InstallArduino.gif b/third-party/TeensyVariablePlayback.O/docs/InstallArduino.gif new file mode 100644 index 0000000..407543c Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/docs/InstallArduino.gif differ diff --git a/third-party/TeensyVariablePlayback.O/docs/dependencies.png b/third-party/TeensyVariablePlayback.O/docs/dependencies.png new file mode 100644 index 0000000..94e3cd4 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/docs/dependencies.png differ diff --git a/third-party/TeensyVariablePlayback.O/examples/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/examples/CMakeLists.txt new file mode 100644 index 0000000..8c0d1bc --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/examples/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.5) +add_subdirectory(array) +add_subdirectory(LittleFS) +add_subdirectory(sampleloader) +add_subdirectory(sd_play_all) +add_subdirectory(sd_raw) +add_subdirectory(sd_wav) +add_subdirectory(SerialFlash) diff --git a/third-party/TeensyVariablePlayback.O/examples/LittleFS/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/examples/LittleFS/CMakeLists.txt new file mode 100644 index 0000000..9951c6b --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/examples/LittleFS/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.10) +project(sd_raw) +set(CMAKE_CXX_STANDARD 14) +add_definitions(-DPROG_FLASH_SIZE=10000) +teensy_include_directories(../../src) +teensy_add_executable(littlefs_raw littlefs_raw.ino) +teensy_target_link_libraries(littlefs_raw teensy_variable_playback SD SdFat Audio LittleFS SPI SerialFlash cores Wire arm_math) diff --git a/third-party/TeensyVariablePlayback.O/examples/LittleFS/littlefs_raw.ino b/third-party/TeensyVariablePlayback.O/examples/LittleFS/littlefs_raw.ino new file mode 100644 index 0000000..4da8c36 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/examples/LittleFS/littlefs_raw.ino @@ -0,0 +1,95 @@ +// 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 + +LittleFS_Program myfs; +#define PROG_FLASH_SIZE 1024 * 1024 * 1 // Specify size to use of onboard Teensy Program Flash chip + +// GUItool: begin automatically generated code +AudioPlayLfsResmp playLfsRaw1(myfs); //xy=324,457 +AudioOutputI2S i2s2; //xy=840.8571472167969,445.5714416503906 +AudioConnection patchCord1(playLfsRaw1, 0, i2s2, 0); +AudioConnection patchCord2(playLfsRaw1, 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; +uint32_t diskSize; + +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 + + // see if the Flash is present and can be initialized: + // lets check to see if the T4 is setup for security first + #if ARDUINO_TEENSY40 + if ((IOMUXC_GPR_GPR11 & 0x100) == 0x100) { + //if security is active max disk size is 960x1024 + if (PROG_FLASH_SIZE > 960 * 1024) { + diskSize = 960 * 1024; + Serial.printf("Security Enables defaulted to %u bytes\n", diskSize); + } else { + diskSize = PROG_FLASH_SIZE; + Serial.printf("Security Not Enabled using %u bytes\n", diskSize); + } + } + #else + diskSize = PROG_FLASH_SIZE; + #endif + + // checks that the LittFS program has started with the disk size specified + if (!myfs.begin(diskSize)) { + Serial.printf("Error starting %s\n", "PROGRAM FLASH DISK"); + while (1) { + // Error, so don't do anything more - stay stuck here + } + } + Serial.println("LittleFS initialized."); + + audioShield.enable(); + audioShield.volume(0.5); + + playLfsRaw1.enableInterpolation(true); + int newsensorValue = analogRead(analogInPin); + playLfsRaw1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + AudioMemory(24); +} + +void loop() { + + int newsensorValue = analogRead(analogInPin); + playLfsRaw1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 500) { + if (!playLfsRaw1.isPlaying()) { + playLfsRaw1.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.O/examples/SerialFlash/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/examples/SerialFlash/CMakeLists.txt new file mode 100644 index 0000000..f08e24c --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/examples/SerialFlash/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.10) +project(serialflash_raw) +set(CMAKE_CXX_STANDARD 14) +add_definitions(-DPROG_FLASH_SIZE=10000) +teensy_include_directories(../../src) +teensy_add_executable(serialflash serialflash.ino) +teensy_target_link_libraries(serialflash teensy_variable_playback Audio SerialFlash SPI cores Wire arm_math) diff --git a/third-party/TeensyVariablePlayback.O/examples/SerialFlash/serialflash.ino b/third-party/TeensyVariablePlayback.O/examples/SerialFlash/serialflash.ino new file mode 100644 index 0000000..ea4e8f0 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/examples/SerialFlash/serialflash.ino @@ -0,0 +1,79 @@ +// 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 + +#define CSPIN 6 + +SerialFlashChip myfs; + +// GUItool: begin automatically generated code +AudioPlaySerialFlashResmp playSerialFlash1(myfs); //xy=324,457 +AudioOutputI2S i2s2; //xy=840.8571472167969,445.5714416503906 +AudioConnection patchCord1(playSerialFlash1, 0, i2s2, 0); +AudioConnection patchCord2(playSerialFlash1, 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; +uint32_t diskSize; + +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 + + + if (!SerialFlash.begin(CSPIN)) { + while (1) { + Serial.println(F("Unable to access SPI Flash chip")); + delay(1000); + } + } + Serial.println("SerialFlash initialized."); + + audioShield.enable(); + audioShield.volume(0.5); + + playSerialFlash1.enableInterpolation(true); + int newsensorValue = analogRead(analogInPin); + playSerialFlash1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + AudioMemory(24); +} + +void loop() { + + int newsensorValue = analogRead(analogInPin); + playSerialFlash1.setPlaybackRate(getPlaybackRate(newsensorValue)); + + unsigned currentMillis = millis(); + if (currentMillis > lastSamplePlayed + 500) { + if (!playSerialFlash1.isPlaying()) { + playSerialFlash1.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.O/examples/array/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/examples/array/CMakeLists.txt new file mode 100644 index 0000000..101a642 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/array/array.ino b/third-party/TeensyVariablePlayback.O/examples/array/array.ino new file mode 100644 index 0000000..13ce0ef --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/midilooper/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/examples/midilooper/CMakeLists.txt new file mode 100644 index 0000000..2e2acbb --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/midilooper/midilooper.ino b/third-party/TeensyVariablePlayback.O/examples/midilooper/midilooper.ino new file mode 100644 index 0000000..dd95858 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/sampleloader/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/examples/sampleloader/CMakeLists.txt new file mode 100644 index 0000000..916c55c --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/sampleloader/README.md b/third-party/TeensyVariablePlayback.O/examples/sampleloader/README.md new file mode 100644 index 0000000..9280162 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/sampleloader/sampleloader.ino b/third-party/TeensyVariablePlayback.O/examples/sampleloader/sampleloader.ino new file mode 100644 index 0000000..605621c --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/sd_play_all/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/examples/sd_play_all/CMakeLists.txt new file mode 100644 index 0000000..77da493 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/sd_play_all/sd_play_all.ino b/third-party/TeensyVariablePlayback.O/examples/sd_play_all/sd_play_all.ino new file mode 100644 index 0000000..41d190d --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/sd_raw/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/examples/sd_raw/CMakeLists.txt new file mode 100644 index 0000000..52de86b --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/sd_raw/sd_raw.ino b/third-party/TeensyVariablePlayback.O/examples/sd_raw/sd_raw.ino new file mode 100644 index 0000000..d651c88 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/sd_wav/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/examples/sd_wav/CMakeLists.txt new file mode 100644 index 0000000..018e7a7 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/examples/sd_wav/sd_wav.ino b/third-party/TeensyVariablePlayback.O/examples/sd_wav/sd_wav.ino new file mode 100644 index 0000000..45bc4cd --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/linux/array/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/extras/linux/array/CMakeLists.txt new file mode 100644 index 0000000..aa54190 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/linux/array/array.cpp b/third-party/TeensyVariablePlayback.O/extras/linux/array/array.cpp new file mode 100644 index 0000000..0a26672 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/linux/sd_raw/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/extras/linux/sd_raw/CMakeLists.txt new file mode 100644 index 0000000..f8ac13d --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/linux/sd_raw/sd_raw.cpp b/third-party/TeensyVariablePlayback.O/extras/linux/sd_raw/sd_raw.cpp new file mode 100644 index 0000000..2ae2411 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/soundio/save_raw/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/extras/soundio/save_raw/CMakeLists.txt new file mode 100644 index 0000000..529b888 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/soundio/save_raw/save_raw.cpp b/third-party/TeensyVariablePlayback.O/extras/soundio/save_raw/save_raw.cpp new file mode 100644 index 0000000..1cfbdd6 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/soundio/save_raw_sd/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/extras/soundio/save_raw_sd/CMakeLists.txt new file mode 100644 index 0000000..02f6b47 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/soundio/save_raw_sd/save_raw_sd.cpp b/third-party/TeensyVariablePlayback.O/extras/soundio/save_raw_sd/save_raw_sd.cpp new file mode 100644 index 0000000..5741e71 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/soundio/save_wav/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/extras/soundio/save_wav/CMakeLists.txt new file mode 100644 index 0000000..837c98e --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/soundio/save_wav/save_wav.cpp b/third-party/TeensyVariablePlayback.O/extras/soundio/save_wav/save_wav.cpp new file mode 100644 index 0000000..fb70fdc --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/soundio/sd_play_all/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/extras/soundio/sd_play_all/CMakeLists.txt new file mode 100644 index 0000000..8b3cb8e --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/extras/soundio/sd_play_all/sd_play_all.cpp b/third-party/TeensyVariablePlayback.O/extras/soundio/sd_play_all/sd_play_all.cpp new file mode 100644 index 0000000..f8fba59 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/keywords.txt b/third-party/TeensyVariablePlayback.O/keywords.txt new file mode 100644 index 0000000..6f5a33f --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/library.json b/third-party/TeensyVariablePlayback.O/library.json new file mode 100644 index 0000000..da4a8d5 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/library.json @@ -0,0 +1,37 @@ +{ + "name": "TeensyVariablePlayback", + "frameworks": "Arduino", + "platforms": "Teensy", + "keywords": "sound, audio, sample, resample, pitch, interpolation, legrange, sampler, playback, speed, loop", + "description": "Teensy Variable Playback", + "url": "https://github.com/newdigate/teensy-variable-playback", + "version": "1.0.16", + "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.O/library.properties b/third-party/TeensyVariablePlayback.O/library.properties new file mode 100644 index 0000000..803798f --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/library.properties @@ -0,0 +1,9 @@ +name=TeensyVariablePlayback +version=1.0.16 +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.O/src/CMakeLists.linux.cmake.in b/third-party/TeensyVariablePlayback.O/src/CMakeLists.linux.cmake.in new file mode 100644 index 0000000..d551486 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/src/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/src/CMakeLists.txt new file mode 100644 index 0000000..cbb2657 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/CMakeLists.txt @@ -0,0 +1,41 @@ +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 + interpolation.cpp + ) + +set(HEADER_FILES + loop_type.h + playresmp.h + playsdresmp.h + ResamplingSdReader.h + waveheaderparser.h + ResamplingArrayReader.h + ResamplingReader.h + playarrayresmp.h + interpolation.h + TeensyVariablePlayback.h + IndexableFile.h + IndexableSerialFlashFile.h + IndexableLittleFSFile.h + IndexableSDFile.h + ResamplingLfsReader.h + ResamplingSerialFlashReader.h + playlfsresmp.h + playserialflashresmp.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.O/src/IndexableFile.h b/third-party/TeensyVariablePlayback.O/src/IndexableFile.h new file mode 100644 index 0000000..a4d4ea6 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/IndexableFile.h @@ -0,0 +1,108 @@ +#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"); + + virtual TFile open(const char *filename) = 0; + + 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)); + } + + virtual ~IndexableFile() { + close(); + } + + 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(); + _file = open(_filename); + } + #endif + next->buffer_size = bytesRead; + _buffers.push_back(next); + match = next; + } + return match->buffer[i % BUFFER_SIZE]; + } + + void close() { + if (_file.available()) { + _file.close(); + } + + for (auto && x : _buffers){ + delete [] x->buffer; + delete x; + } + _buffers.clear(); + + if (_filename != nullptr) { + delete [] _filename; + _filename = nullptr; + } + } + +protected: + TFile _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.O/src/IndexableLittleFSFile.h b/third-party/TeensyVariablePlayback.O/src/IndexableLittleFSFile.h new file mode 100644 index 0000000..e60ec3b --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/IndexableLittleFSFile.h @@ -0,0 +1,43 @@ +#ifndef TEENSY_RESAMPLING_INDEXABLELITTLEFS_FILE_H +#define TEENSY_RESAMPLING_INDEXABLELITTLEFS_FILE_H + +#include +#include "IndexableFile.h" +#include +#include + +namespace newdigate { + +template // BUFFER_SIZE needs to be a power of two +class IndexableLittleFSFile : public IndexableFile { +public: + static_assert(isPowerOf2(BUFFER_SIZE), "BUFFER_SIZE must be a power of 2"); + + IndexableLittleFSFile(LittleFS &fs, const char *filename) : + IndexableFile(filename), + _myFS(fs) + { + IndexableFile::_file = _myFS.open(filename); + } + + File open(const char *filename) override { + return _myFS.open(filename); + } + + virtual ~IndexableLittleFSFile() { + IndexableFile::close(); + } + + int16_t &operator[](int i) { + return IndexableFile::operator[](i); + } + +private: + LittleFS &_myFS; +}; + +} + + + +#endif //TEENSY_RESAMPLING_INDEXABLELITTLEFS_FILE_H diff --git a/third-party/TeensyVariablePlayback.O/src/IndexableSDFile.h b/third-party/TeensyVariablePlayback.O/src/IndexableSDFile.h new file mode 100644 index 0000000..83eb218 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/IndexableSDFile.h @@ -0,0 +1,38 @@ +#ifndef TEENSY_RESAMPLING_INDEXABLESD_FILE_H +#define TEENSY_RESAMPLING_INDEXABLESD_FILE_H + +#include +#include "IndexableFile.h" +#include +#include + +namespace newdigate { + +template // BUFFER_SIZE needs to be a power of two +class IndexableSDFile : public IndexableFile { +public: + static_assert(isPowerOf2(BUFFER_SIZE), "BUFFER_SIZE must be a power of 2"); + + IndexableSDFile(const char *filename) : + IndexableFile(filename) { + IndexableFile::_file = open(filename); + } + + File open(const char *filename) override { + return SD.open(filename); + } + + virtual ~IndexableSDFile() { + IndexableFile::close(); + } + + int16_t &operator[](int i) { + return IndexableFile::operator[](i); + } +}; + +} + + + +#endif diff --git a/third-party/TeensyVariablePlayback.O/src/IndexableSerialFlashFile.h b/third-party/TeensyVariablePlayback.O/src/IndexableSerialFlashFile.h new file mode 100644 index 0000000..fc401aa --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/IndexableSerialFlashFile.h @@ -0,0 +1,43 @@ +#ifndef TEENSY_RESAMPLING_INDEXABLESERIALFLASH_FILE_H +#define TEENSY_RESAMPLING_INDEXABLESERIALFLASH_FILE_H + +#include +#include "IndexableFile.h" +#include +#include + +namespace newdigate { + +template // BUFFER_SIZE needs to be a power of two +class IndexableSerialFlashFile : public IndexableFile { +public: + static_assert(isPowerOf2(BUFFER_SIZE), "BUFFER_SIZE must be a power of 2"); + + IndexableSerialFlashFile(SerialFlashChip &fs, const char *filename) : + IndexableFile(filename), + _myFS(fs) + { + IndexableFile::_file = _myFS.open(filename); + } + + SerialFlashFile open(const char *filename) override { + return _myFS.open(filename); + } + + virtual ~IndexableSerialFlashFile() { + IndexableFile::close(); + } + + int16_t &operator[](int i) { + return IndexableFile::operator[](i); + } + +private: + SerialFlashChip &_myFS; +}; + +} + + + +#endif //TEENSY_RESAMPLING_INDEXABLESERIALFLASH_FILE_H diff --git a/third-party/TeensyVariablePlayback.O/src/ResamplingArrayReader.h b/third-party/TeensyVariablePlayback.O/src/ResamplingArrayReader.h new file mode 100644 index 0000000..5e87fb2 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/ResamplingArrayReader.h @@ -0,0 +1,49 @@ +#ifndef TEENSYAUDIOLIBRARY_RESAMPLINGARRAYREADER_H +#define TEENSYAUDIOLIBRARY_RESAMPLINGARRAYREADER_H + +#include +#include "SD.h" +#include +#include "loop_type.h" +#include "interpolation.h" +#include "ResamplingReader.h" + +namespace newdigate { + +class ResamplingArrayReader : public ResamplingReader { +public: + ResamplingArrayReader() : + ResamplingReader() { + } + + virtual ~ResamplingArrayReader() { + } + + int16_t getSourceBufferValue(long index) override { + return _sourceBuffer[index]; + } + + int available(void) { + return _playing; + } + + int16_t* createSourceBuffer() override { + return _sourceBuffer; + } + + void close(void) override { + if (_playing) { + stop(); + deleteInterpolationPoints(); + } + } + + File open(char *filename) override { + return File(); + } +protected: +}; + +} + +#endif //TEENSYAUDIOLIBRARY_RESAMPLINGARRAYREADER_H diff --git a/third-party/TeensyVariablePlayback.O/src/ResamplingLfsReader.h b/third-party/TeensyVariablePlayback.O/src/ResamplingLfsReader.h new file mode 100644 index 0000000..606286e --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/ResamplingLfsReader.h @@ -0,0 +1,85 @@ +// +// Created by Nicholas Newdigate on 10/02/2019. +// + +#ifndef TEENSYAUDIOLIBRARY_RESAMPLINGLFSREADER_H +#define TEENSYAUDIOLIBRARY_RESAMPLINGLFSREADER_H + +#include +#include "IndexableLittleFSFile.h" +#include "ResamplingReader.h" +#include "LittleFS.h" + +#define RESAMPLE_BUFFER_SAMPLE_SIZE 128 + +#define B2M (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT / 2.0) // 97352592 + +namespace newdigate { + +class ResamplingLfsReader : public ResamplingReader< IndexableLittleFSFile<128, 2>, File > { +public: + ResamplingLfsReader(LittleFS &fs) : + ResamplingReader(), + _myFS(fs) + { + } + virtual ~ResamplingLfsReader() { + } + + int16_t getSourceBufferValue(long index) override { + return (*_sourceBuffer)[index]; + } + + int available(void) + { + return _playing; + } + + File open(char *filename) override { + return _myFS.open(filename); + } + + void close(void) override + { + if (_playing) + stop(); + if (_sourceBuffer != nullptr) { + _sourceBuffer->close(); + delete _sourceBuffer; + _sourceBuffer = nullptr; + } + if (_filename != nullptr) { + delete [] _filename; + _filename = nullptr; + } + deleteInterpolationPoints(); + } + + IndexableLittleFSFile<128, 2>* createSourceBuffer() override { + return new IndexableLittleFSFile<128, 2>(_myFS, _filename); + } + + uint32_t positionMillis(void) { + if (_file_size == 0) return 0; + if (!_useDualPlaybackHead) { + return (uint32_t) (( (double)_bufferPosition1 * lengthMillis() ) / (double)(_file_size/2)); + } else + { + if (_crossfade < 0.5) + return (uint32_t) (( (double)_bufferPosition1 * lengthMillis() ) / (double)(_file_size/2)); + else + return (uint32_t) (( (double)_bufferPosition2 * lengthMillis() ) / (double)(_file_size/2)); + } + } + + uint32_t lengthMillis(void) { + return ((uint64_t)_file_size * B2M) >> 32; + } + +protected: + LittleFS &_myFS; +}; + +} + +#endif //TEENSYAUDIOLIBRARY_RESAMPLINGLFSREADER_H diff --git a/third-party/TeensyVariablePlayback.O/src/ResamplingReader.h b/third-party/TeensyVariablePlayback.O/src/ResamplingReader.h new file mode 100644 index 0000000..6c25f2f --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/ResamplingReader.h @@ -0,0 +1,631 @@ +#ifndef TEENSYAUDIOLIBRARY_RESAMPLINGREADER_H +#define TEENSYAUDIOLIBRARY_RESAMPLINGREADER_H + +#include +#include +#include "loop_type.h" +#include "interpolation.h" +#include "waveheaderparser.h" + +namespace newdigate { + +template +class ResamplingReader { +public: + ResamplingReader() { + } + virtual ~ResamplingReader() { + } + + virtual TFile open(char *filename) = 0; + virtual TArray* createSourceBuffer() = 0; + virtual int16_t getSourceBufferValue(long index) = 0; + virtual void close(void) = 0; + + void begin(void) + { + if (_interpolationType != ResampleInterpolationType::resampleinterpolation_none) { + initializeInterpolationPoints(); + } + _playing = false; + _crossfade = 0.0; + if (_play_start == play_start::play_start_sample) + _bufferPosition1 = _header_offset; + else + _bufferPosition1 = _loop_start; + _file_size = 0; + } + + bool playRaw(TArray *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(); + _playing = true; + return true; + } + + bool playRaw(TArray *array, uint16_t numChannels) { + return playRaw(array, false, numChannels); + } + + bool playWav(TArray *array, uint32_t length) { + return playRaw(array, true); + } + + bool play(const char *filename, bool isWave, uint16_t numChannelsIfRaw = 0) + { + close(); + + if (!isWave) // if raw file, then hardcode the numChannels as per the parameter + setNumChannels(numChannelsIfRaw); + + _filename = new char[strlen(filename)+1] {0}; + memcpy(_filename, filename, strlen(filename) + 1); + + TFile file = open(_filename); + if (!file) { + Serial.printf("Not able to open file: %s\n", _filename); + if (_filename) delete [] _filename; + _filename = nullptr; + return false; + } + + _file_size = file.size(); + if (isWave) { + wav_header wav_header; + wav_data_header data_header; + + WaveHeaderParser wavHeaderParser; + char buffer[36]; + size_t bytesRead = file.read(buffer, 36); + + 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; + + file.close(); + + if (_file_size <= _header_offset * sizeof(int16_t)) { + _playing = false; + if (_filename) delete [] _filename; + _filename = nullptr; + Serial.printf("Wave file contains no samples: %s\n", filename); + return false; + } + + _sourceBuffer = createSourceBuffer(); + _loop_start = _header_offset; + + reset(); + _playing = true; + return true; + } + + bool playRaw(const char *filename, uint16_t numChannelsIfRaw){ + return play(filename, false, numChannelsIfRaw); + } + + bool playWav(const char *filename){ + return play(filename, true); + } + + bool play() + { + stop(); + reset(); + _playing = true; + return true; + } + + void stop(void) + { + if (_playing) { + _playing = false; + } + } + + bool isPlaying(void) { return _playing; } + + unsigned int 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: + { + _crossfade = 0.0; + if (_playbackRate >= 0.0) + _bufferPosition1 = _loop_start; + else + _bufferPosition1 = _loop_finish - _numChannels; + + break; + } + + case looptype_pingpong: + { + if (_playbackRate >= 0.0) { + _bufferPosition1 = _loop_finish - _numChannels; + } + else { + if (_play_start == play_start::play_start_sample) + _bufferPosition1 = _header_offset; + else + _bufferPosition1 = _loop_start; + } + _playbackRate = -_playbackRate; + break; + } + + case looptype_none: + default: + { + //Serial.printf("end of loop...\n"); + /* no looping - return the number of (resampled) bytes returned... */ + close(); + return count; + } + } + } + } + } + return count; + } + + // read the sample value for given channel and store it at the location pointed to by the pointer 'value' + bool readNextValue(int16_t *value, uint16_t channel) { + if (!_useDualPlaybackHead) { + if (_playbackRate >= 0 ) { + //forward playback + if (_bufferPosition1 >= _loop_finish ) + return false; + } else if (_playbackRate < 0) { + // reverse playback + if (_play_start == play_start::play_start_sample) { + if (_bufferPosition1 < _header_offset) + return false; + } else { + if (_bufferPosition1 < _loop_start) + return false; + } + } + } else { + if (_playbackRate >= 0.0) { + if (_crossfade == 0.0 && _bufferPosition1 > (_loop_finish - _numChannels) - _crossfadeDurationInSamples) { + _bufferPosition2 = _loop_start; + _crossfade = 1.0 - (( (_loop_finish-_numChannels) - _bufferPosition1 ) / static_cast(_crossfadeDurationInSamples)); + _crossfadeState = 1; + } else if (_crossfade == 1.0 && _bufferPosition2 > (_loop_finish - _numChannels)- _crossfadeDurationInSamples) { + _bufferPosition1 = _loop_start; + _crossfade = ((_loop_finish - _numChannels) - _bufferPosition2) / static_cast(_crossfadeDurationInSamples); + _crossfadeState = 2; + } else if (_crossfadeState == 1) { + _crossfade = 1.0 - (((_loop_finish - _numChannels) - _bufferPosition1) / static_cast(_crossfadeDurationInSamples)); + if (_crossfade >= 1.0) { + _crossfadeState = 0; + _crossfade = 1.0; + } + } else if (_crossfadeState == 2) { + _crossfade = ( (_loop_finish - _numChannels) - _bufferPosition2 ) / static_cast(_crossfadeDurationInSamples); + if (_crossfade <= 0.0) { + _crossfadeState = 0; + _crossfade = 0.0; + } + } + } else { + if (_crossfade == 0.0 && _bufferPosition1 < _crossfadeDurationInSamples + _header_offset) { + _bufferPosition2 = _loop_finish - _numChannels; + _crossfade = 1.0 - (_bufferPosition1 - _header_offset) / static_cast(_crossfadeDurationInSamples); + _crossfadeState = 1; + } else if (_crossfade == 1.0 && _bufferPosition2 < _crossfadeDurationInSamples + _header_offset) { + _bufferPosition1 = _loop_finish - _numChannels; + _crossfade = (_bufferPosition2 - _header_offset) / static_cast(_crossfadeDurationInSamples); + _crossfadeState = 2; + } else if (_crossfadeState == 1) { + _crossfade = 1.0 - (_bufferPosition1 - _header_offset) / static_cast(_crossfadeDurationInSamples); + if (_crossfade >= 1.0) { + _crossfadeState = 0; + _crossfade = 1.0; + } + } else if (_crossfadeState == 2) { + _crossfade = (_bufferPosition2 - _header_offset) / static_cast(_crossfadeDurationInSamples); + if (_crossfade <= 0.0) { + _crossfadeState = 0; + _crossfade = 0.0; + } + } + } + } + + int16_t result = 0; + if (!_useDualPlaybackHead || _crossfade == 0.0) { + result = getSourceBufferValue(_bufferPosition1 + channel); + } else if (_crossfade == 1.0){ + result = getSourceBufferValue(_bufferPosition2 + channel); + } else{ + int result1 = getSourceBufferValue(_bufferPosition1 + channel); + int result2 = getSourceBufferValue(_bufferPosition2 + channel); + result = ((1.0 - _crossfade ) * result1) + ((_crossfade) * result2); + } + + 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 (!_useDualPlaybackHead) { + if ( _numInterpolationPoints < 2 &&_playbackRate > 1.0 && _bufferPosition1 - _numChannels > _header_offset * 2 ) { + // need to update last sample + _interpolationPoints[channel][1].y = getSourceBufferValue(_bufferPosition1 - _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 (!_useDualPlaybackHead) { + if (_numInterpolationPoints < 2 && _playbackRate < -1.0) { + // need to update last sample + _interpolationPoints[channel][1].y = getSourceBufferValue(_bufferPosition1 + _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; + } + } else { + _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; + _interpolationPoints[channel][1].y = result; + if (_numInterpolationPoints < 2) + _numInterpolationPoints++; + + result =_interpolationPoints[channel][0].y; + } + } + 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; + if (!_useDualPlaybackHead) { + _interpolationPoints[channel][3].y = getSourceBufferValue(_bufferPosition1-(i*_numChannels)+1+channel); + } else + { + _interpolationPoints[channel][3].y = result; + } + 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; + if (!_useDualPlaybackHead) { + _interpolationPoints[channel][3].y = getSourceBufferValue(_bufferPosition1+(i*_numChannels)-1+channel); + } else + { + _interpolationPoints[channel][3].y = result; + } + 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); + if (!_useDualPlaybackHead) { + _bufferPosition1 += (delta * _numChannels); + } else { + if (_crossfade < 1.0) + _bufferPosition1 += (delta * _numChannels); + + if (_crossfade > 0.0) + _bufferPosition2 += (delta * _numChannels); + } + } + + *value = result; + return true; + } + + void setPlaybackRate(double f) { + _playbackRate = f; + if (!_useDualPlaybackHead) { + if (f < 0.0) { + if (_bufferPosition1 <= _header_offset) { + if (_play_start == play_start::play_start_sample) + _bufferPosition1 = _file_size/2 - _numChannels; + else + _bufferPosition1 = _loop_finish - _numChannels; + } + } else { + if (f >= 0.0 && _bufferPosition1 < _header_offset) { + if (_play_start == play_start::play_start_sample) + _bufferPosition1 = _header_offset; + else + _bufferPosition1 = _loop_start; + } + } + } else { + // _useDualPlaybackHead == true + if (_crossfade == 0.0) { + if (f < 0.0) { + if( _bufferPosition1 <= _header_offset) { + if (_play_start == play_start::play_start_sample) + _bufferPosition1 = _file_size/2 - _numChannels; + else + _bufferPosition1 = _loop_finish - _numChannels; + } + } else { + if (f >= 0.0 && _bufferPosition1 < _header_offset) { + _bufferPosition1 = _header_offset; + } + } + } + } + } + + float playbackRate() { + return _playbackRate; + } + + void loop(uint32_t numSamples) { + int bufferPosition = (_crossfade < 1.0)? _bufferPosition1 : _bufferPosition2; + _loop_start = bufferPosition; + _loop_finish = bufferPosition + numSamples * _numChannels; + _loopType = loop_type::looptype_repeat; + } + + void setLoopType(loop_type loopType) + { + _loopType = loopType; + } + + loop_type getLoopType() { + return _loopType; + } + + int available(void) { + return _playing; + } + + void reset(void) { + if (_interpolationType != ResampleInterpolationType::resampleinterpolation_none) { + initializeInterpolationPoints(); + } + _numInterpolationPoints = 0; + if (_playbackRate > 0.0) { + // forward playabck - set _file_offset to first audio block in file + if (_play_start == play_start::play_start_sample) + _bufferPosition1 = _header_offset; + else + _bufferPosition1 = _loop_start; + } else { + // reverse playback - forward _file_offset to last audio block in file + if (_play_start == play_start::play_start_sample) + _bufferPosition1 = _file_size/2 - _numChannels; + else + _bufferPosition1 = _loop_finish - _numChannels; + } + _crossfade = 0.0; + } + + 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 setUseDualPlaybackHead(bool useDualPlaybackHead) { + _useDualPlaybackHead = useDualPlaybackHead; + } + + void setCrossfadeDurationInSamples(unsigned int crossfadeDurationInSamples) { + _crossfadeDurationInSamples = crossfadeDurationInSamples; + } + + 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; + } + + void setPlayStart(play_start start) { + _play_start = start; + } + + #define B2M (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT / 2.0) // 97352592 + uint32_t positionMillis() + { + return ((uint64_t)_file_size * B2M) >> 32; + } + + uint32_t lengthMillis() + { + return ((uint64_t)_file_size * B2M) >> 32; + } + +protected: + 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 = loop_type::looptype_none; + play_start _play_start = play_start::play_start_sample; + int _bufferPosition1 = 0; + int _bufferPosition2 = 0; + double _crossfade = 0.0; + bool _useDualPlaybackHead = false; + unsigned int _crossfadeDurationInSamples = 256; + int _crossfadeState = 0; + int32_t _loop_start = 0; + int32_t _loop_finish = 0; + int16_t _numChannels = -1; + uint16_t _numInterpolationPointsChannels = 0; + char *_filename = nullptr; + TArray *_sourceBuffer = nullptr; + + ResampleInterpolationType _interpolationType = ResampleInterpolationType::resampleinterpolation_none; + unsigned int _numInterpolationPoints = 0; + InterpolationData **_interpolationPoints = nullptr; + + void 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 deleteInterpolationPoints(void) + { + if (!_interpolationPoints) return; + for (int i=0; i<_numInterpolationPointsChannels; i++) { + delete [] _interpolationPoints[i]; + } + delete [] _interpolationPoints; + _interpolationPoints = nullptr; + _numInterpolationPointsChannels = 0; + } + +}; + +} + +#endif //TEENSYAUDIOLIBRARY_RESAMPLINGREADER_H diff --git a/third-party/TeensyVariablePlayback.O/src/ResamplingSdReader.h b/third-party/TeensyVariablePlayback.O/src/ResamplingSdReader.h new file mode 100644 index 0000000..fae4ca2 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/ResamplingSdReader.h @@ -0,0 +1,88 @@ +// +// 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 "IndexableSDFile.h" +#include "ResamplingReader.h" + +#define RESAMPLE_BUFFER_SAMPLE_SIZE 128 + +#define B2M (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT / 2.0) // 97352592 + +namespace newdigate { + +class ResamplingSdReader : public ResamplingReader< IndexableSDFile<128, 4>, File > { +public: + ResamplingSdReader() : + ResamplingReader() + { + } + + virtual ~ResamplingSdReader() { + } + + int16_t getSourceBufferValue(long index) override { + return (*_sourceBuffer)[index]; + } + + int available(void) + { + return _playing; + } + + File open(char *filename) override { + return SD.open(filename); + } + + void close(void) override + { + if (_playing) + stop(); + if (_sourceBuffer != nullptr) { + _sourceBuffer->close(); + delete _sourceBuffer; + _sourceBuffer = nullptr; + } + if (_filename != nullptr) { + delete [] _filename; + _filename = nullptr; + } + deleteInterpolationPoints(); + } + + IndexableSDFile<128, 4>* createSourceBuffer() override { + return new IndexableSDFile<128, 4>(_filename); + } + + uint32_t positionMillis(void) { + if (_file_size == 0) return 0; + if (!_useDualPlaybackHead) { + return (uint32_t) (( (double)_bufferPosition1 * lengthMillis() ) / (double)(_file_size/2)); + } else + { + if (_crossfade < 0.5) + return (uint32_t) (( (double)_bufferPosition1 * lengthMillis() ) / (double)(_file_size/2)); + else + return (uint32_t) (( (double)_bufferPosition2 * lengthMillis() ) / (double)(_file_size/2)); + } + } + + uint32_t lengthMillis(void) { + return ((uint64_t)_file_size * B2M) >> 32; + } + +protected: + +}; + +} + +#endif //TEENSYAUDIOLIBRARY_RESAMPLINGSDREADER_H diff --git a/third-party/TeensyVariablePlayback.O/src/ResamplingSerialFlashReader.h b/third-party/TeensyVariablePlayback.O/src/ResamplingSerialFlashReader.h new file mode 100644 index 0000000..8dafd13 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/ResamplingSerialFlashReader.h @@ -0,0 +1,89 @@ +// +// Created by Nicholas Newdigate on 10/02/2019. +// + +#ifndef TEENSYAUDIOLIBRARY_RESAMPLINGSERIALFLASHREADER_H +#define TEENSYAUDIOLIBRARY_RESAMPLINGSERIALFLASHREADER_H + +#include +#include "spi_interrupt.h" +#include "loop_type.h" +#include "interpolation.h" +#include "IndexableSerialFlashFile.h" +#include "ResamplingReader.h" +#include "SerialFlash.h" + +#define RESAMPLE_BUFFER_SAMPLE_SIZE 128 + +#define B2M (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT / 2.0) // 97352592 + +namespace newdigate { + +class ResamplingSerialFlashReader : public ResamplingReader< IndexableSerialFlashFile<128, 2>, SerialFlashFile > { +public: + ResamplingSerialFlashReader(SerialFlashChip &fs) : + ResamplingReader(), + _myFS(fs) + { + } + + virtual ~ResamplingSerialFlashReader() { + } + + int16_t getSourceBufferValue(long index) override { + return (*_sourceBuffer)[index]; + } + + int available(void) + { + return _playing; + } + + SerialFlashFile open(char *filename) override { + return _myFS.open(filename); + } + + void close(void) override + { + if (_playing) + stop(); + if (_sourceBuffer != nullptr) { + _sourceBuffer->close(); + delete _sourceBuffer; + _sourceBuffer = nullptr; + } + if (_filename != nullptr) { + delete [] _filename; + _filename = nullptr; + } + deleteInterpolationPoints(); + } + + IndexableSerialFlashFile<128, 2>* createSourceBuffer() override { + return new IndexableSerialFlashFile<128, 2>(_myFS, _filename); + } + + uint32_t positionMillis(void) { + if (_file_size == 0) return 0; + if (!_useDualPlaybackHead) { + return (uint32_t) (( (double)_bufferPosition1 * lengthMillis() ) / (double)(_file_size/2)); + } else + { + if (_crossfade < 0.5) + return (uint32_t) (( (double)_bufferPosition1 * lengthMillis() ) / (double)(_file_size/2)); + else + return (uint32_t) (( (double)_bufferPosition2 * lengthMillis() ) / (double)(_file_size/2)); + } + } + + uint32_t lengthMillis(void) { + return ((uint64_t)_file_size * B2M) >> 32; + } + +protected: + SerialFlashChip &_myFS; +}; + +} + +#endif //TEENSYAUDIOLIBRARY_RESAMPLINGSERIALFLASHREADER_H diff --git a/third-party/TeensyVariablePlayback.O/src/TeensyVariablePlayback.h b/third-party/TeensyVariablePlayback.O/src/TeensyVariablePlayback.h new file mode 100644 index 0000000..eec731d --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/TeensyVariablePlayback.h @@ -0,0 +1,17 @@ +// +// 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 "ResamplingLfsReader.h" +#include "ResamplingSerialFlashReader.h" +#include "playsdresmp.h" +#include "playarrayresmp.h" +#include "playlfsresmp.h" +#include "playserialflashresmp.h" +#endif //TEENSY_RESAMPLING_ARDUINO_SAMPLER_H diff --git a/third-party/TeensyVariablePlayback.O/src/interpolation.cpp b/third-party/TeensyVariablePlayback.O/src/interpolation.cpp new file mode 100644 index 0000000..fff75f5 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/src/interpolation.h b/third-party/TeensyVariablePlayback.O/src/interpolation.h new file mode 100644 index 0000000..fcb46e6 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/src/loop_type.h b/third-party/TeensyVariablePlayback.O/src/loop_type.h new file mode 100644 index 0000000..5364ef0 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/loop_type.h @@ -0,0 +1,19 @@ +// +// 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; + +typedef enum play_start { + play_start_sample, + play_start_loop, +} play_start; + +#endif //TEENSY_RESAMPLING_LOOP_TYPE_H diff --git a/third-party/TeensyVariablePlayback.O/src/playarrayresmp.h b/third-party/TeensyVariablePlayback.O/src/playarrayresmp.h new file mode 100644 index 0000000..4f37701 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/playarrayresmp.h @@ -0,0 +1,30 @@ +// +// 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() + { + reader = new newdigate::ResamplingArrayReader(); + begin(); + } + + virtual ~AudioPlayArrayResmp() { + delete reader; + } +}; + + +#endif //TEENSY_RESAMPLING_SDREADER_PLAYARRAYRESMP_H diff --git a/third-party/TeensyVariablePlayback.O/src/playlfsresmp.h b/third-party/TeensyVariablePlayback.O/src/playlfsresmp.h new file mode 100644 index 0000000..5774441 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/playlfsresmp.h @@ -0,0 +1,26 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_PLAYLFSRAWRESMP_H +#define TEENSY_RESAMPLING_SDREADER_PLAYLFSRAWRESMP_H + +#include "ResamplingLfsReader.h" + +class AudioPlayLfsResmp : public AudioPlayResmp +{ +public: + AudioPlayLfsResmp(LittleFS &fs) : + AudioPlayResmp() + { + reader = new newdigate::ResamplingLfsReader(fs); + begin(); + } + + virtual ~AudioPlayLfsResmp() { + delete reader; + } +}; + + +#endif //TEENSY_RESAMPLING_SDREADER_PLAYLFSRAWRESMP_H diff --git a/third-party/TeensyVariablePlayback.O/src/playresmp.h b/third-party/TeensyVariablePlayback.O/src/playresmp.h new file mode 100644 index 0000000..e02ab76 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/playresmp.h @@ -0,0 +1,151 @@ +#ifndef TEENSY_RESAMPLING_SDREADER_PLAYRESMP_H +#define TEENSY_RESAMPLING_SDREADER_PLAYRESMP_H + +#include "Arduino.h" +#include "Audio.h" +#include "loop_type.h" + +template +class AudioPlayResmp : public AudioStream +{ + public: + AudioPlayResmp(): AudioStream(0, NULL), reader(nullptr) + { + } + + virtual ~AudioPlayResmp() { + } + + void begin(void) + { + reader->begin(); + } + + bool playRaw(const char *filename, uint16_t numChannels) + { + stop(); + return reader->play(filename, false, numChannels); + } + + bool playWav(const char *filename) + { + stop(); + return reader->play(filename, true, 0); + } + + bool playRaw(int16_t *data, uint32_t numSamples, uint16_t numChannels) + { + stop(); + return reader->playRaw(data, numSamples, numChannels); + } + + bool playRaw(const unsigned int *data, uint32_t numSamples, uint16_t numChannels) + { + return playRaw((int16_t *) data, numSamples, numChannels); + } + + bool playWav(int16_t *data, uint32_t fileSize) + { + stop(); + return reader->playWav(data, fileSize); + } + + bool playWav(const unsigned int *data, uint32_t fileSize) { + return playWav((int16_t *) data, fileSize); + } + + void setPlaybackRate(float f) { + reader->setPlaybackRate(f); + } + + void setLoopType(loop_type t) { + reader->setLoopType(t); + } + + void setLoopStart(uint32_t loop_start) { + reader->setLoopStart(loop_start); + } + + void setLoopFinish(uint32_t loop_finish) { + reader->setLoopFinish(loop_finish); + } + + void setUseDualPlaybackHead(bool useDualPlaybackHead) { + reader->setUseDualPlaybackHead(useDualPlaybackHead); + } + + void setCrossfadeDurationInSamples(unsigned int crossfadeDurationInSamples) { + reader->setCrossfadeDurationInSamples(crossfadeDurationInSamples); + } + + void setPlayStart(play_start start) { + reader->setPlayStart(start); + } + + void enableInterpolation(bool enable) { + if (enable) + reader->setInterpolationType(ResampleInterpolationType::resampleinterpolation_quadratic); + else + reader->setInterpolationType(ResampleInterpolationType::resampleinterpolation_none); + } + + bool isPlaying(void) { + return reader->isPlaying(); + }; + + void stop() { + reader->stop(); + } + + void update() + { + int _numChannels = reader->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 (!reader->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 (reader->available()) { + // we can read more data from the file... + n = reader->read((void**)data, AUDIO_BLOCK_SAMPLES); + for (int channel=0; channel < _numChannels; channel++) { + memset( &blocks[channel]->data[n], 0, (AUDIO_BLOCK_SAMPLES - n) * 2); + transmit(blocks[channel], channel); + } + + if(_numChannels == 1) { + transmit(blocks[0], 1); + } + } else { + reader->close(); + } + for (int channel=0; channel < _numChannels; channel++) { + release(blocks[channel]); + } + } + uint32_t positionMillis() + { + return reader->positionMillis(); + } + + uint32_t lengthMillis() + { + return reader->lengthMillis(); + } + + protected: + TResamplingReader *reader; +}; + +#endif // TEENSY_RESAMPLING_SDREADER_PLAYRESMP_H \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback.O/src/playsdresmp.h b/third-party/TeensyVariablePlayback.O/src/playsdresmp.h new file mode 100644 index 0000000..fdc039d --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/playsdresmp.h @@ -0,0 +1,32 @@ +// +// 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() + { + reader = new newdigate::ResamplingSdReader(); + begin(); + } + + virtual ~AudioPlaySdResmp() { + delete reader; + } +}; + + +#endif //TEENSY_RESAMPLING_SDREADER_PLAYSDRAWRESMP_H diff --git a/third-party/TeensyVariablePlayback.O/src/playserialflashresmp.h b/third-party/TeensyVariablePlayback.O/src/playserialflashresmp.h new file mode 100644 index 0000000..6dc56d5 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/playserialflashresmp.h @@ -0,0 +1,31 @@ +// +// Created by Nicholas Newdigate on 18/07/2020. +// + +#ifndef TEENSY_RESAMPLING_SDREADER_PLAYSERIALFLASHRAWRESMP_H +#define TEENSY_RESAMPLING_SDREADER_PLAYSERIALFLASHRAWRESMP_H + +#include "Arduino.h" +#include "AudioStream.h" +#include "SerialFlash.h" +#include "stdint.h" +#include "ResamplingSerialFlashReader.h" +#include "playresmp.h" + +class AudioPlaySerialFlashResmp : public AudioPlayResmp +{ +public: + AudioPlaySerialFlashResmp(SerialFlashChip &fs) : + AudioPlayResmp() + { + reader = new newdigate::ResamplingSerialFlashReader(fs); + begin(); + } + + virtual ~AudioPlaySerialFlashResmp() { + delete reader; + } +}; + + +#endif //TEENSY_RESAMPLING_SDREADER_PLAYSERIALFLASHRAWRESMP_H diff --git a/third-party/TeensyVariablePlayback.O/src/waveheaderparser.h b/third-party/TeensyVariablePlayback.O/src/waveheaderparser.h new file mode 100644 index 0000000..e8d7a56 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/src/waveheaderparser.h @@ -0,0 +1,181 @@ +// +// 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] = {0,0,0,0}; // 00 - 03 - Contains "RIFF" + int header_chunk_size = 0; // 04 - 07 - Size of the wav portion of the file, which follows the first 8 bytes. File size - 8 + char wave_header[4] = {0,0,0,0}; // 08 - 11 - Contains "WAVE" + + // Format Header + char fmt_header[4] = {0,0,0,0}; // 12 - 15 - Contains "fmt " (includes trailing space) + int fmt_chunk_size = 0; // 16 - 19 - Should be 16 for PCM + short audio_format = 0; // 20 - 21 - Should be 1 for PCM. 3 for IEEE Float + short num_channels = 0; // 22 - 23 + int sample_rate = 0; // 24 - 27 + int byte_rate = 0; // 28 - 31 + short sample_alignment = 0; // 32 - 33 + short bit_depth = 0; // 34 - 35 +}; + +struct wav_data_header { + // Data + char data_header[4] = {0,0,0,0}; // 36 - 39 + unsigned int data_bytes = 0;// 40 - 43 +}; + +class WaveHeaderParser { +public: + bool readWaveHeader(const char *filename, wav_header &header, wav_data_header &wav_data_header) { + File wavFile = SD.open(filename); + 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]; + int bytesRead = wavFile.read(buffer, 36); + 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.O/test.sh b/third-party/TeensyVariablePlayback.O/test.sh new file mode 100755 index 0000000..b31b446 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/test.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cd cmake-build-debug/test/ +./tests diff --git a/third-party/TeensyVariablePlayback.O/test/CMakeLists.txt b/third-party/TeensyVariablePlayback.O/test/CMakeLists.txt new file mode 100644 index 0000000..74b6efc --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/audio/array/AudioArrayFixture.h b/third-party/TeensyVariablePlayback.O/test/audio/array/AudioArrayFixture.h new file mode 100644 index 0000000..5a38de9 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/audio/array/test_array_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/audio/array/test_array_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..0428821 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/audio/array/test_array_stereo_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/audio/array/test_array_stereo_loop_forward_playback.cpp new file mode 100644 index 0000000..f0e83fc --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/audio/output_test.cpp b/third-party/TeensyVariablePlayback.O/test/audio/output_test.cpp new file mode 100644 index 0000000..0170502 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/audio/output_test.h b/third-party/TeensyVariablePlayback.O/test/audio/output_test.h new file mode 100644 index 0000000..2eb9232 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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"); + } + std::string outputPath = std::string(cwd) + "/" + std::string(path); + __filesystem::path p(outputPath); + if (! __filesystem::exists(p) ) + __filesystem::create_directories(outputPath); + + _filePath = outputPath + std::string(filename); + std::cout << "saving output audio .wav file to " << _filePath << std::endl; + _outputFile.open(_filePath, std::ios_base::trunc | std::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, std::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, std::ios_base::beg); + _outputFile.write(buf, 4); + + short bytespersampleframe = numChannels * 2; + buf[1] = bytespersampleframe >> 8; + buf[0] = bytespersampleframe; + _outputFile.seekp(32, std::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, std::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.O/test/audio/wav/AudioWavFixture.h b/third-party/TeensyVariablePlayback.O/test/audio/wav/AudioWavFixture.h new file mode 100644 index 0000000..2cb5bba --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/audio/wav/test_wav_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/audio/wav/test_wav_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..a771dd5 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/audio/wav/test_wav_stereo_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/audio/wav/test_wav_stereo_loop_forward_playback.cpp new file mode 100644 index 0000000..fa1738d --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/audio/wav/test_wav_tags.cpp b/third-party/TeensyVariablePlayback.O/test/audio/wav/test_wav_tags.cpp new file mode 100644 index 0000000..5b9226a --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/boost-to-junit-xml.xslt b/third-party/TeensyVariablePlayback.O/test/boost-to-junit-xml.xslt new file mode 100644 index 0000000..bee89f9 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/embedfile.c b/third-party/TeensyVariablePlayback.O/test/embedfile.c new file mode 100644 index 0000000..f08244b --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/array/ResamplingArrayFixture.h b/third-party/TeensyVariablePlayback.O/test/low_level/array/ResamplingArrayFixture.h new file mode 100644 index 0000000..0490daf --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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 newdigate::ResamplingArrayReader(); + } + + ~ResamplingArrayFixture() { + delete resamplingArrayReader; + } + + newdigate::ResamplingArrayReader * resamplingArrayReader; +}; + +#endif //TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYFIXTURE_H diff --git a/third-party/TeensyVariablePlayback.O/test/low_level/array/test_array_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/array/test_array_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..acd2c1b --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/array/test_array_stereo_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/array/test_array_stereo_loop_forward_playback.cpp new file mode 100644 index 0000000..cc88552 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/arraywav/ResamplingArrayWavFixture.h b/third-party/TeensyVariablePlayback.O/test/low_level/arraywav/ResamplingArrayWavFixture.h new file mode 100644 index 0000000..f954704 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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 newdigate::ResamplingArrayReader(); + } + + ~ResamplingArrayWavFixture() { + delete resamplingArrayReader; + } + + newdigate::ResamplingArrayReader * resamplingArrayReader; +}; + +#endif //TEENSY_RESAMPLING_SDREADER_RESAMPLINGARRAYWAVFIXTURE_H diff --git a/third-party/TeensyVariablePlayback.O/test/low_level/arraywav/test_array_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/arraywav/test_array_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..7d16e68 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/arraywav/test_array_stereo_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/arraywav/test_array_stereo_loop_forward_playback.cpp new file mode 100644 index 0000000..7364f28 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/indexedfile/IndexedFileFixture.h b/third-party/TeensyVariablePlayback.O/test/low_level/indexedfile/IndexedFileFixture.h new file mode 100644 index 0000000..967d844 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/indexedfile/test_indexablefile.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/indexedfile/test_indexablefile.cpp new file mode 100644 index 0000000..017d38c --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/test/low_level/indexedfile/test_indexablefile.cpp @@ -0,0 +1,32 @@ +#include +#include "IndexedFileFixture.h" + +#include +#include "IndexableSDFile.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.O/test/low_level/sd/ResamplingReaderFixture.h b/third-party/TeensyVariablePlayback.O/test/low_level/sd/ResamplingReaderFixture.h new file mode 100644 index 0000000..692829a --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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 newdigate::ResamplingSdReader(); + } + + ~ResamplingReaderFixture() { + delete resamplingSdReader; + } + + newdigate::ResamplingSdReader * resamplingSdReader; +}; + +#endif //TEENSY_RESAMPLING_SDREADER_RESAMPLINGREADERFIXTURE_H diff --git a/third-party/TeensyVariablePlayback.O/test/low_level/sd/readme.MD b/third-party/TeensyVariablePlayback.O/test/low_level/sd/readme.MD new file mode 100755 index 0000000..fcaf731 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/sd/test_raw_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/sd/test_raw_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..f899930 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/sd/test_raw_mono_noloop_forward_double_rate_playback.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/sd/test_raw_mono_noloop_forward_double_rate_playback.cpp new file mode 100644 index 0000000..2928607 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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, newdigate::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.O/test/low_level/sd/test_raw_mono_noloop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/sd/test_raw_mono_noloop_forward_playback.cpp new file mode 100644 index 0000000..e575ceb --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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->play("test2.bin", false, 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.O/test/low_level/sd/test_wav_mono_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/sd/test_wav_mono_loop_forward_playback.cpp new file mode 100644 index 0000000..f708675 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/sd/test_wav_mono_noloop_backward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/sd/test_wav_mono_noloop_backward_playback.cpp new file mode 100644 index 0000000..d185763 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/sd/test_wav_mono_noloop_forward_playback.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/sd/test_wav_mono_noloop_forward_playback.cpp new file mode 100644 index 0000000..09f249d --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/wav_header/WaveHeaderParserFixture.h b/third-party/TeensyVariablePlayback.O/test/low_level/wav_header/WaveHeaderParserFixture.h new file mode 100644 index 0000000..aacd82e --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/low_level/wav_header/test_parse_wave_header.cpp b/third-party/TeensyVariablePlayback.O/test/low_level/wav_header/test_parse_wave_header.cpp new file mode 100644 index 0000000..59096e2 --- /dev/null +++ b/third-party/TeensyVariablePlayback.O/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.O/test/resources/input/PNO1C1.raw b/third-party/TeensyVariablePlayback.O/test/resources/input/PNO1C1.raw new file mode 100644 index 0000000..099e256 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/input/PNO1C1.raw differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/input/SDTEST1.wav b/third-party/TeensyVariablePlayback.O/test/resources/input/SDTEST1.wav new file mode 100644 index 0000000..2b0d694 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/input/SDTEST1.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/input/SDTEST2.wav b/third-party/TeensyVariablePlayback.O/test/resources/input/SDTEST2.wav new file mode 100644 index 0000000..ff06d67 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/input/SDTEST2.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/input/kick.raw b/third-party/TeensyVariablePlayback.O/test/resources/input/kick.raw new file mode 100644 index 0000000..67a7a7f Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/input/kick.raw differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/input/kick.wav b/third-party/TeensyVariablePlayback.O/test/resources/input/kick.wav new file mode 100644 index 0000000..6e477c2 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/input/kick.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/input/mono_souljah.wav b/third-party/TeensyVariablePlayback.O/test/resources/input/mono_souljah.wav new file mode 100644 index 0000000..206d8ed Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/input/mono_souljah.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/input/stereo_souljah.raw b/third-party/TeensyVariablePlayback.O/test/resources/input/stereo_souljah.raw new file mode 100644 index 0000000..c739709 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/input/stereo_souljah.raw differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/input/stereo_souljah.wav b/third-party/TeensyVariablePlayback.O/test/resources/input/stereo_souljah.wav new file mode 100644 index 0000000..c21f987 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/input/stereo_souljah.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_0_5000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_0_5000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_0_5000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_0_5000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_0_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_0_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_0_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_0_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_1_0000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_1_0000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_1_0000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_1_0000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_1_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_1_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_1_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_1_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_2_0000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_2_0000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_2_0000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_2_0000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_8_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_8_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Array_fwd_8_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Array_fwd_8_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/SDTEST1.wav b/third-party/TeensyVariablePlayback.O/test/resources/reference/SDTEST1.wav new file mode 100644 index 0000000..60793b6 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/reference/SDTEST1.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/SDTEST2.wav b/third-party/TeensyVariablePlayback.O/test/resources/reference/SDTEST2.wav new file mode 100644 index 0000000..1fa5819 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/reference/SDTEST2.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_0_5000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_0_5000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_0_5000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_0_5000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_0_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_0_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_0_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_0_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_1_0000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_1_0000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_1_0000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_1_0000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_1_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_1_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_1_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_1_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_2_0000_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_2_0000_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_2_0000_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_2_0000_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_8_7437_quadratic_mono_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_8_7437_quadratic_mono_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/Wav_fwd_8_7437_quadratic_stereo_noloop.wav b/third-party/TeensyVariablePlayback.O/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.O/test/resources/reference/Wav_fwd_8_7437_quadratic_stereo_noloop.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/kick.wav b/third-party/TeensyVariablePlayback.O/test/resources/reference/kick.wav new file mode 100644 index 0000000..6e477c2 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/reference/kick.wav differ diff --git a/third-party/TeensyVariablePlayback.O/test/resources/reference/stereo_souljah.wav b/third-party/TeensyVariablePlayback.O/test/resources/reference/stereo_souljah.wav new file mode 100644 index 0000000..c21f987 Binary files /dev/null and b/third-party/TeensyVariablePlayback.O/test/resources/reference/stereo_souljah.wav differ diff --git a/third-party/TeensyVariablePlayback/.github/FUNDING.yml b/third-party/TeensyVariablePlayback/.github/FUNDING.yml new file mode 100644 index 0000000..a865742 --- /dev/null +++ b/third-party/TeensyVariablePlayback/.github/FUNDING.yml @@ -0,0 +1,3 @@ +github: [newdigate] +patreon: teensy_eurorack +custom: ["paypal.me/nicnewdigate"] diff --git a/third-party/TeensyVariablePlayback/.github/workflows/soundio.yml b/third-party/TeensyVariablePlayback/.github/workflows/soundio.yml new file mode 100644 index 0000000..3906c59 --- /dev/null +++ b/third-party/TeensyVariablePlayback/.github/workflows/soundio.yml @@ -0,0 +1,32 @@ +name: test + +on: + push: + paths-ignore: + - 'docs/**' + - 'README.md' + - 'LICENSE' + - '.gitignore' + - 'examples/**' + - '.github/workflows/teensy*.yml' +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Debug + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: download dependencies + run: sudo apt-get update && sudo apt-get install -yq libsoundio-dev + + - name: where are my libs folders + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: ls /lib && ls /usr/lib && ls /usr/local/lib + + - name: where is soundio + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: dpkg -L libsoundio-dev \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_array.yml b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_array.yml new file mode 100644 index 0000000..54c8d84 --- /dev/null +++ b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_array.yml @@ -0,0 +1,106 @@ +name: example-array-t41 + +on: + push: + paths-ignore: + - 'docs/**' + - '**.md' + - '.github/workflows/ubuntu_x64_cmake.yml' + + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: actions/checkout@v2 + with: + repository: newdigate/teensy-cmake-macros + path: deps/teensy-cmake-macros + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/cores.git + path: deps/cores + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Audio.git + path: deps/Audio + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SD.git + path: deps/SD + fetch-depth: 1 + ref: Juse_Use_SdFat + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Wire.git + path: deps/Wire + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SPI.git + path: deps/SPI + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SerialFlash.git + path: deps/SerialFlash + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/arm_math.git + path: deps/arm_math + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SdFat.git + path: deps/SdFat + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/LittleFS.git + path: deps/LittleFS + fetch-depth: 1 + ref: main + + - name: download toolchain + run: | + curl -L "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2" --output /tmp/gcc-arm-none-eabi.tar.bz2 + mkdir -p /opt + cd /opt + tar xjf /tmp/gcc-arm-none-eabi.tar.bz2 + rm /tmp/gcc-arm-none-eabi.tar.bz2 + echo "/opt/gcc-arm-none-eabi-9-2019-q4-major/bin" + + - name: install teensy-cmake-macros + run: cd deps/teensy-cmake-macros && mkdir cmake-build-debug && cd cmake-build-debug && cmake -DCMAKE_BUILD_TYPE=Debug .. && sudo make install + + - name: build + run: mkdir cmake-build-debug && cd cmake-build-debug && cmake .. -DCMAKE_TOOLCHAIN_FILE:FILEPATH="${{github.workspace}}/cmake/toolchains/teensy41.cmake" && make array_hex + + - uses: actions/upload-artifact@v2 + with: + name: hex file + path: examples/array/cmake-build-debug/array.hex diff --git a/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_littlefs.yml b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_littlefs.yml new file mode 100644 index 0000000..6e6620d --- /dev/null +++ b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_littlefs.yml @@ -0,0 +1,113 @@ +name: example-littlefs-t41 + +on: + push: + paths-ignore: + - 'docs/**' + - '**.md' + - '.github/workflows/ubuntu_x64_cmake.yml' + + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: actions/checkout@v2 + with: + repository: newdigate/teensy-cmake-macros + path: deps/teensy-cmake-macros + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/cores.git + path: deps/cores + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Audio.git + path: deps/Audio + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SD.git + path: deps/SD + fetch-depth: 1 + ref: Juse_Use_SdFat + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Wire.git + path: deps/Wire + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SPI.git + path: deps/SPI + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SerialFlash.git + path: deps/SerialFlash + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/arm_math.git + path: deps/arm_math + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SdFat.git + path: deps/SdFat + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/LittleFS.git + path: deps/LittleFS + fetch-depth: 1 + ref: main + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SerialFlash.git + path: deps/SerialFlash + fetch-depth: 1 + ref: master + + - name: download toolchain + run: | + curl -L "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2" --output /tmp/gcc-arm-none-eabi.tar.bz2 + mkdir -p /opt + cd /opt + tar xjf /tmp/gcc-arm-none-eabi.tar.bz2 + rm /tmp/gcc-arm-none-eabi.tar.bz2 + echo "/opt/gcc-arm-none-eabi-9-2019-q4-major/bin" + + - name: install teensy-cmake-macros + run: cd deps/teensy-cmake-macros && mkdir cmake-build-debug && cd cmake-build-debug && cmake -DCMAKE_BUILD_TYPE=Debug .. && sudo make install + + - name: build + run: mkdir cmake-build-debug && cd cmake-build-debug && cmake .. -DCMAKE_TOOLCHAIN_FILE:FILEPATH="${{github.workspace}}/cmake/toolchains/teensy41.cmake" && make littlefs_raw_hex + + - uses: actions/upload-artifact@v2 + with: + name: hex file + path: examples/LittleFS/cmake-build-debug/littlefs_raw.hex diff --git a/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_sdraw.yml b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_sdraw.yml new file mode 100644 index 0000000..18ede1e --- /dev/null +++ b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_sdraw.yml @@ -0,0 +1,106 @@ +name: example-sdraw-t41 + +on: + push: + paths-ignore: + - 'docs/**' + - '**.md' + - '.github/workflows/ubuntu_x64_cmake.yml' + + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: actions/checkout@v2 + with: + repository: newdigate/teensy-cmake-macros + path: deps/teensy-cmake-macros + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/cores.git + path: deps/cores + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Audio.git + path: deps/Audio + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SD.git + path: deps/SD + fetch-depth: 1 + ref: Juse_Use_SdFat + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Wire.git + path: deps/Wire + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SPI.git + path: deps/SPI + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SerialFlash.git + path: deps/SerialFlash + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/arm_math.git + path: deps/arm_math + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SdFat.git + path: deps/SdFat + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/LittleFS.git + path: deps/LittleFS + fetch-depth: 1 + ref: main + + - name: download toolchain + run: | + curl -L "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2" --output /tmp/gcc-arm-none-eabi.tar.bz2 + mkdir -p /opt + cd /opt + tar xjf /tmp/gcc-arm-none-eabi.tar.bz2 + rm /tmp/gcc-arm-none-eabi.tar.bz2 + echo "/opt/gcc-arm-none-eabi-9-2019-q4-major/bin" + + - name: install teensy-cmake-macros + run: cd deps/teensy-cmake-macros && mkdir cmake-build-debug && cd cmake-build-debug && cmake -DCMAKE_BUILD_TYPE=Debug .. && sudo make install + + - name: build + run: mkdir cmake-build-debug && cd cmake-build-debug && cmake .. -DCMAKE_TOOLCHAIN_FILE:FILEPATH="${{github.workspace}}/cmake/toolchains/teensy41.cmake" && make sd_raw_hex + + - uses: actions/upload-artifact@v2 + with: + name: hex file + path: examples/sd_raw/cmake-build-debug/sd_raw.hex diff --git a/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_sdwav.yml b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_sdwav.yml new file mode 100644 index 0000000..ab20e28 --- /dev/null +++ b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_sdwav.yml @@ -0,0 +1,106 @@ +name: example-sdwav-t41 + +on: + push: + paths-ignore: + - 'docs/**' + - '**.md' + - '.github/workflows/ubuntu_x64_cmake.yml' + + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: actions/checkout@v2 + with: + repository: newdigate/teensy-cmake-macros + path: deps/teensy-cmake-macros + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/cores.git + path: deps/cores + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Audio.git + path: deps/Audio + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SD.git + path: deps/SD + fetch-depth: 1 + ref: Juse_Use_SdFat + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Wire.git + path: deps/Wire + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SPI.git + path: deps/SPI + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SerialFlash.git + path: deps/SerialFlash + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/arm_math.git + path: deps/arm_math + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SdFat.git + path: deps/SdFat + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/LittleFS.git + path: deps/LittleFS + fetch-depth: 1 + ref: main + + - name: download toolchain + run: | + curl -L "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2" --output /tmp/gcc-arm-none-eabi.tar.bz2 + mkdir -p /opt + cd /opt + tar xjf /tmp/gcc-arm-none-eabi.tar.bz2 + rm /tmp/gcc-arm-none-eabi.tar.bz2 + echo "/opt/gcc-arm-none-eabi-9-2019-q4-major/bin" + + - name: install teensy-cmake-macros + run: cd deps/teensy-cmake-macros && mkdir cmake-build-debug && cd cmake-build-debug && cmake -DCMAKE_BUILD_TYPE=Debug .. && sudo make install + + - name: build + run: mkdir cmake-build-debug && cd cmake-build-debug && cmake .. -DCMAKE_TOOLCHAIN_FILE:FILEPATH="${{github.workspace}}/cmake/toolchains/teensy41.cmake" && make sd_wav_hex + + - uses: actions/upload-artifact@v2 + with: + name: hex file + path: examples/sd_wav/cmake-build-debug/sd_wav.hex diff --git a/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_serialflash.yml b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_serialflash.yml new file mode 100644 index 0000000..5881acd --- /dev/null +++ b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_ex_serialflash.yml @@ -0,0 +1,113 @@ +name: example-serialflash-t41 + +on: + push: + paths-ignore: + - 'docs/**' + - '**.md' + - '.github/workflows/ubuntu_x64_cmake.yml' + + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: actions/checkout@v2 + with: + repository: newdigate/teensy-cmake-macros + path: deps/teensy-cmake-macros + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/cores.git + path: deps/cores + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Audio.git + path: deps/Audio + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SD.git + path: deps/SD + fetch-depth: 1 + ref: Juse_Use_SdFat + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Wire.git + path: deps/Wire + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SPI.git + path: deps/SPI + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SerialFlash.git + path: deps/SerialFlash + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/arm_math.git + path: deps/arm_math + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SdFat.git + path: deps/SdFat + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/LittleFS.git + path: deps/LittleFS + fetch-depth: 1 + ref: main + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SerialFlash.git + path: deps/SerialFlash + fetch-depth: 1 + ref: master + + - name: download toolchain + run: | + curl -L "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2" --output /tmp/gcc-arm-none-eabi.tar.bz2 + mkdir -p /opt + cd /opt + tar xjf /tmp/gcc-arm-none-eabi.tar.bz2 + rm /tmp/gcc-arm-none-eabi.tar.bz2 + echo "/opt/gcc-arm-none-eabi-9-2019-q4-major/bin" + + - name: install teensy-cmake-macros + run: cd deps/teensy-cmake-macros && mkdir cmake-build-debug && cd cmake-build-debug && cmake -DCMAKE_BUILD_TYPE=Debug .. && sudo make install + + - name: build + run: mkdir cmake-build-debug && cd cmake-build-debug && cmake .. -DCMAKE_TOOLCHAIN_FILE:FILEPATH="${{github.workspace}}/cmake/toolchains/teensy41.cmake" && make serialflash_hex + + - uses: actions/upload-artifact@v2 + with: + name: hex file + path: examples/SerialFlash/cmake-build-debug/serialflash.hex diff --git a/third-party/TeensyVariablePlayback/.github/workflows/teensy41_lib.yml b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_lib.yml new file mode 100644 index 0000000..c27f11f --- /dev/null +++ b/third-party/TeensyVariablePlayback/.github/workflows/teensy41_lib.yml @@ -0,0 +1,106 @@ +name: lib-teensy41 + +on: + push: + paths-ignore: + - 'docs/**' + - '**.md' + - '.github/workflows/ubuntu_x64_cmake.yml' + + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: actions/checkout@v2 + with: + repository: newdigate/teensy-cmake-macros + path: deps/teensy-cmake-macros + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/cores.git + path: deps/cores + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Audio.git + path: deps/Audio + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SD.git + path: deps/SD + fetch-depth: 1 + ref: Juse_Use_SdFat + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/Wire.git + path: deps/Wire + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SPI.git + path: deps/SPI + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SerialFlash.git + path: deps/SerialFlash + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/arm_math.git + path: deps/arm_math + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/SdFat.git + path: deps/SdFat + fetch-depth: 1 + ref: master + + - uses: actions/checkout@v2 + with: + repository: PaulStoffregen/LittleFS.git + path: deps/LittleFS + fetch-depth: 1 + ref: main + + - name: download toolchain + run: | + curl -L "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2" --output /tmp/gcc-arm-none-eabi.tar.bz2 + mkdir -p /opt + cd /opt + tar xjf /tmp/gcc-arm-none-eabi.tar.bz2 + rm /tmp/gcc-arm-none-eabi.tar.bz2 + echo "/opt/gcc-arm-none-eabi-9-2019-q4-major/bin" + + - name: install teensy-cmake-macros + run: cd deps/teensy-cmake-macros && mkdir cmake-build-debug && cd cmake-build-debug && cmake -DCMAKE_BUILD_TYPE=Debug .. && sudo make install + + - name: build + run: mkdir cmake-build-debug && cd cmake-build-debug && cmake .. -DCMAKE_TOOLCHAIN_FILE:FILEPATH="${{github.workspace}}/cmake/toolchains/teensy41.cmake" && make teensy_variable_playback.o + + - uses: actions/upload-artifact@v2 + with: + name: hex file + path: src/cmake-build-debug/libteensy_variable_playback.o.a diff --git a/third-party/TeensyVariablePlayback/.github/workflows/ubuntu_x64_cmake.yml b/third-party/TeensyVariablePlayback/.github/workflows/ubuntu_x64_cmake.yml new file mode 100644 index 0000000..0beb787 --- /dev/null +++ b/third-party/TeensyVariablePlayback/.github/workflows/ubuntu_x64_cmake.yml @@ -0,0 +1,99 @@ +name: Ubuntu-x64 + +on: + push: + paths-ignore: + - 'docs/**' + - 'README.md' + - 'LICENSE' + - '.gitignore' + - 'examples/**' + - '.github/workflows/teensy*.yml' +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Debug + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally + # well on Windows or Mac. You can convert this to a matrix build if you need + # cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: actions/checkout@v2 + with: + repository: newdigate/teensy-x86-stubs + path: teensy-x86-stubs + + - uses: actions/checkout@v2 + with: + repository: newdigate/teensy-audio-x86-stubs + path: teensy-audio-x86-stubs + + - uses: actions/checkout@v2 + with: + repository: newdigate/teensy-x86-sd-stubs + path: teensy-x86-sd-stubs + + - name: download dependencies + run: sudo apt-get update && sudo apt-get install -yq libboost-test-dev libsoundio-dev libxml2-utils xsltproc + + - name: Make and Install teensy-x86-stubs + run: cd teensy-x86-stubs && mkdir cmake-build-$BUILD_TYPE && cd cmake-build-$BUILD_TYPE && cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. && sudo make install + + - name: Make and Install teensy-x86-sd-stubs + run: cd teensy-x86-sd-stubs && mkdir cmake-build-$BUILD_TYPE && cd cmake-build-$BUILD_TYPE && cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. && sudo make install + + - name: Make and Install teensy-audio-x86-stubs + run: cd teensy-audio-x86-stubs/src && mkdir cmake-build-$BUILD_TYPE && cd cmake-build-$BUILD_TYPE && cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. && sudo make install + + - name: Make and Install teensy-audio-x86-stubs-soundio + run: cd teensy-audio-x86-stubs/extras/soundio/src && mkdir cmake-build-$BUILD_TYPE && cd cmake-build-$BUILD_TYPE && cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. && sudo make install + + - name: Create Build Environment + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: cmake -E make_directory ${{github.workspace}}/build + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment variable + # access regardless of the host operating system + shell: bash + working-directory: ${{github.workspace}}/build + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. + # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE + + - name: Build + working-directory: ${{github.workspace}}/build + shell: bash + # Execute the build. You can specify a specific target with "--target " + run: cmake --build . --config $BUILD_TYPE + + - name: Test + working-directory: ${{github.workspace}} + shell: bash + # Execute the build. You can specify a specific target with "--target " + run: | + mkdir output + build/test/tests --output_format=XML --report_level=detailed 2> output/test-results.xml + xmllint --format output/test-results.xml > output/test-results-formatted.xml + xsltproc test/boost-to-junit-xml.xslt output/test-results.xml > output/junit-test-results.xml + + - name: upload artifacts + if: always() + uses: actions/upload-artifact@v1 + with: + name: test-audio-output + path: output + + - name: Publish Unit Test Results + uses: EnricoMi/publish-unit-test-result-action@v1 + if: always() + with: + files: output/junit-test-results.xml \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/.gitignore b/third-party/TeensyVariablePlayback/.gitignore new file mode 100644 index 0000000..81c933e --- /dev/null +++ b/third-party/TeensyVariablePlayback/.gitignore @@ -0,0 +1,34 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +cmake-build-debug \ No newline at end of file diff --git a/third-party/TeensyVariablePlayback/src/IndexableSDFile.h b/third-party/TeensyVariablePlayback/src/IndexableSDFile.h index 83eb218..d73ee8d 100644 --- a/third-party/TeensyVariablePlayback/src/IndexableSDFile.h +++ b/third-party/TeensyVariablePlayback/src/IndexableSDFile.h @@ -13,13 +13,15 @@ class IndexableSDFile : public IndexableFile public: static_assert(isPowerOf2(BUFFER_SIZE), "BUFFER_SIZE must be a power of 2"); - IndexableSDFile(const char *filename) : - IndexableFile(filename) { + IndexableSDFile(const char *filename, SDClass &sd) : + IndexableFile(filename), + _sd(sd) + { IndexableFile::_file = open(filename); } File open(const char *filename) override { - return SD.open(filename); + return _sd.open(filename); } virtual ~IndexableSDFile() { @@ -29,6 +31,8 @@ public: int16_t &operator[](int i) { return IndexableFile::operator[](i); } +protected: + SDClass &_sd; }; } diff --git a/third-party/TeensyVariablePlayback/src/ResamplingReader.h b/third-party/TeensyVariablePlayback/src/ResamplingReader.h index 6c25f2f..a7455c7 100644 --- a/third-party/TeensyVariablePlayback/src/ResamplingReader.h +++ b/third-party/TeensyVariablePlayback/src/ResamplingReader.h @@ -21,6 +21,7 @@ public: virtual TArray* createSourceBuffer() = 0; virtual int16_t getSourceBufferValue(long index) = 0; virtual void close(void) = 0; + int _lastInterpolationPosition[8] = {0}; void begin(void) { @@ -60,6 +61,35 @@ public: return playRaw(array, true); } + bool playWav(TArray *array) { + bool result = false; + + do + { + wav_header hdr; + unsigned infoTagsSize; + wav_data_header wav_data_hdr; + WaveHeaderParser parser; + + if (!parser.readWaveHeaderFromBuffer((char*) array, hdr)) + break; + + // make unwarranted assumptions about the header format + // by using a magic number... + if (!parser.readInfoTags((unsigned char*) array, 36, infoTagsSize)) + break; + + if (!parser.readDataHeader((unsigned char*) array, 36 + infoTagsSize, wav_data_hdr)) + break; + + result = playRaw((TArray*)((char*) array + (36 + infoTagsSize + sizeof wav_data_hdr)), + wav_data_hdr.data_bytes / 2, + hdr.num_channels); + } while (0); + + return result; + } + bool play(const char *filename, bool isWave, uint16_t numChannelsIfRaw = 0) { close(); @@ -303,52 +333,56 @@ public: if (_remainder - _playbackRate < 0.0){ // we crossed over a whole number, make sure we update the samples for interpolation if (!_useDualPlaybackHead) { - if ( _numInterpolationPoints < 2 &&_playbackRate > 1.0 && _bufferPosition1 - _numChannels > _header_offset * 2 ) { + if ( _numInterpolationPoints[channel] < 2 &&_playbackRate > 1.0 && _bufferPosition1 - _numChannels > _header_offset * 2 ) { // need to update last sample _interpolationPoints[channel][1].y = getSourceBufferValue(_bufferPosition1 - _numChannels); } } _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; _interpolationPoints[channel][1].y = result; - if (_numInterpolationPoints < 2) - _numInterpolationPoints++; + if (_numInterpolationPoints[channel] < 2) + _numInterpolationPoints[channel]++; } } else if (_playbackRate < 0) { if (_remainder - _playbackRate > 0.0){ // we crossed over a whole number, make sure we update the samples for interpolation if (!_useDualPlaybackHead) { - if (_numInterpolationPoints < 2 && _playbackRate < -1.0) { + if (_numInterpolationPoints[channel] < 2 && _playbackRate < -1.0) { // need to update last sample _interpolationPoints[channel][1].y = getSourceBufferValue(_bufferPosition1 + _numChannels); } } _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; _interpolationPoints[channel][1].y = result; - if (_numInterpolationPoints < 2) - _numInterpolationPoints++; + if (_numInterpolationPoints[channel] < 2) + _numInterpolationPoints[channel]++; } } - if (_numInterpolationPoints > 1) { + if (_numInterpolationPoints[channel] > 1) { result = abs_remainder * _interpolationPoints[channel][1].y + (1.0 - abs_remainder) * _interpolationPoints[channel][0].y; } } else { _interpolationPoints[channel][0].y = _interpolationPoints[channel][1].y; _interpolationPoints[channel][1].y = result; - if (_numInterpolationPoints < 2) - _numInterpolationPoints++; + if (_numInterpolationPoints[channel] < 2) + _numInterpolationPoints[channel]++; result =_interpolationPoints[channel][0].y; } } else if (_interpolationType == ResampleInterpolationType::resampleinterpolation_quadratic) { - double abs_remainder = abs(_remainder); - if (abs_remainder > 0.0) { + int delta = abs(_bufferPosition1/_numChannels - _lastInterpolationPosition[channel]); + //Serial.printf("delta %d %d:\n", delta, _bufferPosition1/_numChannels - _lastInterpolationPosition[channel]); + if (_numInterpolationPoints[channel] == 0){ + _interpolationPoints[channel][3].y = result; + _numInterpolationPoints[channel] = 1; + } + if (delta > 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); + int numberOfSamplesToUpdate = delta; if (numberOfSamplesToUpdate > 4) numberOfSamplesToUpdate = 4; // if playbackrate > 4, only need to pop last 4 samples for (int i=numberOfSamplesToUpdate; i > 0; i--) { @@ -359,16 +393,18 @@ public: _interpolationPoints[channel][3].y = getSourceBufferValue(_bufferPosition1-(i*_numChannels)+1+channel); } else { - _interpolationPoints[channel][3].y = result; + _interpolationPoints[channel][3].y = + getSourceBufferValue(_bufferPosition1-(i*_numChannels)+1+channel) * _crossfade + + + getSourceBufferValue(_bufferPosition2-(i*_numChannels)+1+channel) * (1.0 -_crossfade); } - if (_numInterpolationPoints < 4) _numInterpolationPoints++; + if (_numInterpolationPoints[channel] < 4) _numInterpolationPoints[channel]++; } - } + _lastInterpolationPosition[channel] = _bufferPosition1 / _numChannels; } 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); + int numberOfSamplesToUpdate = delta; if (numberOfSamplesToUpdate > 4) numberOfSamplesToUpdate = 4; // if playbackrate > 4, only need to pop last 4 samples for (int i=numberOfSamplesToUpdate; i > 0; i--) { @@ -379,40 +415,47 @@ public: _interpolationPoints[channel][3].y = getSourceBufferValue(_bufferPosition1+(i*_numChannels)-1+channel); } else { - _interpolationPoints[channel][3].y = result; + _interpolationPoints[channel][3].y = + getSourceBufferValue(_bufferPosition1+(i*_numChannels)-1+channel) * _crossfade + + + getSourceBufferValue(_bufferPosition2+(i*_numChannels)-1+channel) * (1.0 - _crossfade); } - if (_numInterpolationPoints < 4) _numInterpolationPoints++; + if (_numInterpolationPoints[channel] < 4) _numInterpolationPoints[channel]++; + _lastInterpolationPosition[channel] = _bufferPosition1 / _numChannels; } - } - } - - 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; + } + } + if (_remainder != 0.0) { + if (_numInterpolationPoints[channel] >= 4) { + //result = interpolate(_interpolationPoints[channel], _interpolationPoints[channel][0].x + ((_bufferPosition1 - _interpolationPoints[channel][0].x) * 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)); + /* + Serial.printf("[%d %d %d %d] @ %f = %d \n", + _interpolationPoints[channel][0].y, + _interpolationPoints[channel][1].y, + _interpolationPoints[channel][2].y, + _interpolationPoints[channel][3].y, + 1.0 + abs(_remainder), + interpolation + ); + */ + result = 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++; + if (_numInterpolationPoints[channel] < 4) { result = 0; } else result = _interpolationPoints[channel][1].y; - //Serial.printf("%f\n", result); } } - + if (channel == _numChannels - 1) { _remainder += _playbackRate; @@ -428,7 +471,7 @@ public: _bufferPosition2 += (delta * _numChannels); } } - + //Serial.printf("ch: %d, index: %d, value: %d\n", channel, _bufferPosition1, result); *value = result; return true; } @@ -498,7 +541,7 @@ public: if (_interpolationType != ResampleInterpolationType::resampleinterpolation_none) { initializeInterpolationPoints(); } - _numInterpolationPoints = 0; + if (_playbackRate > 0.0) { // forward playabck - set _file_offset to first audio block in file if (_play_start == play_start::play_start_sample) @@ -512,6 +555,15 @@ public: else _bufferPosition1 = _loop_finish - _numChannels; } + + for(int i=0;i<8;i++) { + _numInterpolationPoints[i] = 0; + if (_playbackRate > 0.0) + _lastInterpolationPosition[i] = _bufferPosition1 / _numChannels; + else + _lastInterpolationPosition[i] = (_bufferPosition1 / _numChannels) + 1; + } + _crossfade = 0.0; } @@ -568,6 +620,34 @@ public: { return ((uint64_t)_file_size * B2M) >> 32; } + + int getBufferPosition1() { + return _bufferPosition1; + } + + int getBufferPosition2() { + return _bufferPosition2; + } + + double getCrossfade() { + return _crossfade; + } + + bool getUseDualPlaybackHead(){ + return _useDualPlaybackHead; + } + + unsigned int getCrossfadeDurationInSamples() { + return _crossfadeDurationInSamples; + } + + int32_t getLooptStart() { + return _loop_start / _numChannels - _header_offset; + } + + int32_t getLoopFinish() { + return _loop_finish / _numChannels - _header_offset; + } protected: volatile bool _playing = false; @@ -593,7 +673,7 @@ protected: TArray *_sourceBuffer = nullptr; ResampleInterpolationType _interpolationType = ResampleInterpolationType::resampleinterpolation_none; - unsigned int _numInterpolationPoints = 0; + unsigned int _numInterpolationPoints[8] = {0}; InterpolationData **_interpolationPoints = nullptr; void initializeInterpolationPoints(void) { diff --git a/third-party/TeensyVariablePlayback/src/ResamplingSdReader.h b/third-party/TeensyVariablePlayback/src/ResamplingSdReader.h index fae4ca2..c9c0390 100644 --- a/third-party/TeensyVariablePlayback/src/ResamplingSdReader.h +++ b/third-party/TeensyVariablePlayback/src/ResamplingSdReader.h @@ -21,8 +21,9 @@ namespace newdigate { class ResamplingSdReader : public ResamplingReader< IndexableSDFile<128, 4>, File > { public: - ResamplingSdReader() : - ResamplingReader() + ResamplingSdReader(SDClass &sd = SD) : + ResamplingReader(), + _sd(sd) { } @@ -39,7 +40,7 @@ public: } File open(char *filename) override { - return SD.open(filename); + return _sd.open(filename); } void close(void) override @@ -59,7 +60,7 @@ public: } IndexableSDFile<128, 4>* createSourceBuffer() override { - return new IndexableSDFile<128, 4>(_filename); + return new IndexableSDFile<128, 4>(_filename, _sd); } uint32_t positionMillis(void) { @@ -80,7 +81,7 @@ public: } protected: - + SDClass &_sd; }; } diff --git a/third-party/TeensyVariablePlayback/src/TeensyVariablePlayback.h b/third-party/TeensyVariablePlayback/src/TeensyVariablePlayback.h index eec731d..c94072f 100644 --- a/third-party/TeensyVariablePlayback/src/TeensyVariablePlayback.h +++ b/third-party/TeensyVariablePlayback/src/TeensyVariablePlayback.h @@ -8,10 +8,12 @@ #include "waveheaderparser.h" #include "ResamplingSdReader.h" #include "ResamplingArrayReader.h" -#include "ResamplingLfsReader.h" -#include "ResamplingSerialFlashReader.h" #include "playsdresmp.h" #include "playarrayresmp.h" +#ifndef BUILD_FOR_LINUX +#include "ResamplingLfsReader.h" +#include "ResamplingSerialFlashReader.h" #include "playlfsresmp.h" #include "playserialflashresmp.h" +#endif #endif //TEENSY_RESAMPLING_ARDUINO_SAMPLER_H diff --git a/third-party/TeensyVariablePlayback/src/playresmp.h b/third-party/TeensyVariablePlayback/src/playresmp.h index e02ab76..4ca6052 100644 --- a/third-party/TeensyVariablePlayback/src/playresmp.h +++ b/third-party/TeensyVariablePlayback/src/playresmp.h @@ -54,6 +54,12 @@ class AudioPlayResmp : public AudioStream return playWav((int16_t *) data, fileSize); } + bool playWav(int16_t *data) + { + stop(); + return reader->playWav(data); + } + void setPlaybackRate(float f) { reader->setPlaybackRate(f); } @@ -99,11 +105,12 @@ class AudioPlayResmp : public AudioStream void update() { + bool gotBlocks = true; int _numChannels = reader->getNumChannels(); if (_numChannels == -1) return; - unsigned int i, n; + unsigned int n; audio_block_t *blocks[_numChannels]; int16_t *data[_numChannels]; // only update if we're playing @@ -112,28 +119,40 @@ class AudioPlayResmp : public AudioStream // 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 (blocks[i] == nullptr) + gotBlocks = false; + else + data[i] = blocks[i]->data; } - if (reader->available()) { - // we can read more data from the file... - n = reader->read((void**)data, AUDIO_BLOCK_SAMPLES); - for (int channel=0; channel < _numChannels; channel++) { - memset( &blocks[channel]->data[n], 0, (AUDIO_BLOCK_SAMPLES - n) * 2); - transmit(blocks[channel], channel); - } - - if(_numChannels == 1) { - transmit(blocks[0], 1); - } - } else { - reader->close(); - } - for (int channel=0; channel < _numChannels; channel++) { - release(blocks[channel]); + if (gotBlocks) // enough blocks, do the transmit + { + if (reader->available()) { + // we can read more data from the file... + n = reader->read((void**)data, AUDIO_BLOCK_SAMPLES); + for (int channel=0; channel < _numChannels; channel++) { + memset( &blocks[channel]->data[n], 0, (AUDIO_BLOCK_SAMPLES - n) * 2); + transmit(blocks[channel], channel); + } + + if(_numChannels == 1) { + transmit(blocks[0], 1); + } + + } else { + reader->close(); + } + } + + // release all allocated blocks, even if there + // weren't enough and we couldn't transmit + for (int channel=0; channel < _numChannels; channel++) + { + if (nullptr != blocks[channel]) // only release if allocated! + release(blocks[channel]); } } + uint32_t positionMillis() { return reader->positionMillis(); @@ -144,6 +163,26 @@ class AudioPlayResmp : public AudioStream return reader->lengthMillis(); } + double getCrossFade() { + return reader->getCrossfade(); + } + + int getBufferPosition1() { + return reader->getBufferPosition1(); + } + + int getBufferPosition2() { + return reader->getBufferPosition2(); + } + + bool getUseDualPlaybackHead() { + return reader->getUseDualPlaybackHead(); + } + + int32_t getLoopFinish() { + return reader->getLoopFinish(); + } + protected: TResamplingReader *reader; }; diff --git a/third-party/TeensyVariablePlayback/src/playsdresmp.h b/third-party/TeensyVariablePlayback/src/playsdresmp.h index fdc039d..f33291f 100644 --- a/third-party/TeensyVariablePlayback/src/playsdresmp.h +++ b/third-party/TeensyVariablePlayback/src/playsdresmp.h @@ -16,12 +16,13 @@ class AudioPlaySdResmp : public AudioPlayResmp { public: - AudioPlaySdResmp(void) : + AudioPlaySdResmp(SDClass &sd = SD) : AudioPlayResmp() { - reader = new newdigate::ResamplingSdReader(); + reader = new newdigate::ResamplingSdReader(sd); begin(); } + virtual ~AudioPlaySdResmp() { delete reader; diff --git a/third-party/TeensyVariablePlayback/test/CMakeLists.txt b/third-party/TeensyVariablePlayback/test/CMakeLists.txt index 74b6efc..72f8738 100644 --- a/third-party/TeensyVariablePlayback/test/CMakeLists.txt +++ b/third-party/TeensyVariablePlayback/test/CMakeLists.txt @@ -51,7 +51,9 @@ if (DEFINED BUILD_FOR_LINUX) audio/output_test.cpp audio/array/AudioArrayFixture.h + audio/array/test_array_mono_loop_backward_playback.cpp audio/array/test_array_mono_loop_forward_playback.cpp + audio/array/test_array_stereo_loop_backward_playback.cpp audio/array/test_array_stereo_loop_forward_playback.cpp audio/wav/AudioWavFixture.h diff --git a/third-party/TeensyVariablePlayback/test/audio/array/test_array_mono_loop_backward_playback.cpp b/third-party/TeensyVariablePlayback/test/audio/array/test_array_mono_loop_backward_playback.cpp new file mode 100644 index 0000000..19231a6 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/array/test_array_mono_loop_backward_playback.cpp @@ -0,0 +1,270 @@ +// +// 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_backward_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_bwd_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_bwd_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_bwd_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_bwd_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_bwd_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_bwd_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_bwd_2_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 = -2.5; + const std::string testName = "Array_bwd_2_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_bwd_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_bwd_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_bwd_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_bwd_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_bwd_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_bwd_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_backward_playback.cpp b/third-party/TeensyVariablePlayback/test/audio/array/test_array_stereo_loop_backward_playback.cpp new file mode 100644 index 0000000..a9ebf49 --- /dev/null +++ b/third-party/TeensyVariablePlayback/test/audio/array/test_array_stereo_loop_backward_playback.cpp @@ -0,0 +1,270 @@ +// +// 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_backward_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_bwd_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_bwd_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_bwd_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_bwd_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_bwd_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_bwd_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_bwd_2_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 = -2.5; + const std::string testName = "Array_bwd_2_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; + + } + + + BOOST_FIXTURE_TEST_CASE(Array_bwd_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_bwd_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_bwd_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_bwd_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_bwd_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_bwd_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/array/test_array_stereo_loop_forward_playback.cpp b/third-party/TeensyVariablePlayback/test/audio/array/test_array_stereo_loop_forward_playback.cpp index f0e83fc..7077047 100644 --- 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 @@ -125,6 +125,37 @@ BOOST_AUTO_TEST_SUITE(test_audio_array_stereo_loop_forward_playback) BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2); } + BOOST_FIXTURE_TEST_CASE(Array_fwd_2_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 = 2.5; + const std::string testName = "Array_fwd_2_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; + + } + + BOOST_FIXTURE_TEST_CASE(Array_fwd_0_7437_quadratic_stereo_noloop, AudioArrayFixture) { // GUItool: begin automatically generated code diff --git a/third-party/TeensyVariablePlayback/test/low_level/indexedfile/test_indexablefile.cpp b/third-party/TeensyVariablePlayback/test/low_level/indexedfile/test_indexablefile.cpp index 017d38c..b4047fe 100644 --- a/third-party/TeensyVariablePlayback/test/low_level/indexedfile/test_indexablefile.cpp +++ b/third-party/TeensyVariablePlayback/test/low_level/indexedfile/test_indexablefile.cpp @@ -15,7 +15,7 @@ BOOST_AUTO_TEST_SUITE(test_indexablefile) } SD.setSDCardFileData((char*)file_contents, sample_size * 2); - newdigate::IndexableSDFile<16, 2> indexable("blah.h"); // use max 2 buffers, with 16 elements each.... + newdigate::IndexableSDFile<16, 2> indexable("blah.h", SD); // use max 2 buffers, with 16 elements each.... /* for (int i=0; i